
# 创建通用文件系统
#### 操作场景
通用文件系统是SFS中存储文件的容器。您需要先创建一个通用文件系统，然后才能在SFS中存储数据。
下面介绍如何调用[创建通用文件系统 - CreateFileSystem](https://support.huaweicloud.com/api-sfs/sfs_02_0112.html)API在指定的区域创建一个通用文件系统，API的调用方法请参见[如何调用API](https://support.huaweicloud.com/api-sfs/sfs_02_0100.html)。
#### 前提条件
- 已获取AK和SK，获取方法参见[获取访问密钥（AK/SK）](https://support.huaweicloud.com/api-sfs/sfs_02_0120.html)。
- 您需要规划通用文件系统所在的区域信息，并根据区域确定调用API的Endpoint，详细信息请参见[终端节点](https://support.huaweicloud.com/api-sfs/sfs_02_0001.html#sfs_02_0001__section16809182104910)。
区域一旦确定，创建完成后无法修改。
#### 在cn-north-4区域创建一个名为filesystem001的通用文件系统
示例中使用通用的Apache Http Client。
```
package com.sfsclient;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
public class TestMain {
    // 您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。如果使用硬编码可能会存在泄露风险。
    // 您可以登录访问管理控制台获取访问密钥AK/SK
    public static String accessKey = System.getenv("HUAWEICLOUD_SDK_AK");
    public static String securityKey = System.getenv("HUAWEICLOUD_SDK_SK"); 
    public static String region = "cn-east-3"; // 取值为规划通用文件系统所在的区域
    public static String endpoint = "sfs3.cn-east-3.myhuaweicloud.com"; // 通用文件系统服务地址
    
    public static String createSfsBody =
            "<CreateBucketConfiguration >\n" +
                    "<Location>" + region + "</Location>\n" +
                    "</CreateBucketConfiguration>";
    public static void main(String[] str) {
        createFileSystem();
    }
    private static void createFileSystem() {
        // 通用文件系统名称
        String fileSystemName = "example-sfs-001";
        String httpMethod = "PUT";
        String date = DateUtils.formatDate(System.currentTimeMillis());
        String contentType = "application/xml";
        /** 根据请求计算签名**/
        String contentMD5 = "";
        String canonicalizedHeaders = "x-obs-bucket-type:SFS";
        String canonicalizedResource = "/" + fileSystemName ;
        // Content-MD5 、Content-Type 没有直接换行， data格式为RFC 1123，和请求中的时间一致
        String stringToSign = httpMethod + "\n" +
                contentMD5 + "\n" +
                contentType + "\n" +
                date + "\n" +
                canonicalizedHeaders  + "\n" + canonicalizedResource;
        System.out.printf("StringToSign:\n[%s]\n\n", stringToSign);
        HttpURLConnection conn = null;
        try {
            String signature = Signature.signWithHmacSha1(securityKey, stringToSign);
            String authorization= "OBS " + accessKey + ":" + signature;
            System.out.printf("authorization:%s\n\n", authorization);
            URL url = new URL("http://" + endpoint + "/" + fileSystemName);
            conn = (HttpURLConnection) url.openConnection();
            // 增加签名头域
            conn.setRequestMethod(httpMethod);
            conn.setRequestProperty("Date", date);
            conn.setRequestProperty("Content-Type", contentType);
            conn.setRequestProperty("x-obs-bucket-type", "SFS");
            conn.setRequestProperty("Authorization", authorization);
            conn.setDoOutput(true);
            // 增加body体
            OutputStream out = conn.getOutputStream();
            out.write(createSfsBody.getBytes());
            out.flush();
            out.close();
            String status = conn.getHeaderField(null);
            System.out.println(status);
            // 输出收到的响应消息
            Map<String, List<String>> headers = conn.getHeaderFields();
            for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
                String key = entry.getKey();
                List<String> values = entry.getValue();
                if (key != null) {
                    for (String value : values) {
                        System.out.println(key + ": " + value);
                    }
                }
            }
            // 请求出错处理
            int statusCode = conn.getResponseCode();
            if (statusCode != HttpURLConnection.HTTP_OK && statusCode != HttpURLConnection.HTTP_NO_CONTENT) {
                InputStream errorStream = conn.getErrorStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream));
                StringBuilder responseBody = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    responseBody.append(line);
                }
                reader.close();
                System.out.println("Error: " + responseBody);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (conn != null){
                conn.disconnect();
            }
        }
    }
}
```
**其中Date头域DateUtils的格式为：**
```
package com.sfsclient;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;
public class DateUtils {
    public static String formatDate(long time)
    {
        DateFormat serverDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
        serverDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return serverDateFormat.format(time);
    }
}
```
**签名字符串Signature的计算方法为：**
```
package com.sfsclient;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.util.Base64;
public class Signature {
    public static String signWithHmacSha1(String sk, String canonicalString) throws UnsupportedEncodingException {
        try {
            SecretKeySpec signingKey = new SecretKeySpec(sk.getBytes("UTF-8"), "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(signingKey);
            return Base64.getEncoder().encodeToString(mac.doFinal(canonicalString.getBytes("UTF-8")));
        } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
}
```
