閱讀106 返回首頁    go 網易 go 網易蜂巢


對象存儲 Java SDK

目錄

安裝

Java環境

JDK 6 及以上版本

Maven項目中使用

在 Maven 工程中使用 NOS Java SDK 隻需在 pom.xml 中加入相應依賴即可

   <dependency>
     <groupId>com.netease.cloud</groupId>
     <artifactId>nos-sdk-java-publiccloud</artifactId>
     <version>0.0.1</version>
   </dependency>

工程中直接引用jar

  • 下載包含Java SDK及其依賴的開發包: nos-sdk-java-publiccloud-0.0.1.tar.gz
  • 解壓該開發包;
  • 將解壓後文件夾下 lib 文件夾中的 nos-sdk-java-publiccloud-0.0.1.jar 以及 third-party 文件夾下的所有 jar 文件拷貝到你的項目中;
  • 在 Eclipse 中選擇你的工程,右擊 -> Properties -> Java Build Path -> Add JARs;
  • 選中你在第三步拷貝的所有 JAR 文件;

前言

Java SDK 提供的接口都在 NosClient 中實現,並以成員方法的方式對外提供調用。因此使用 Java SDK 前必須實例化一個 NosClient 對象。

關於請求參數

NosClient中的方法一般都提供兩種參數傳入方式:

  • 普通傳參方式
nosClient.createBucket(bucketName);
  • request對象傳參方式
     CreateBucketRequest request = new CreateBucketRequest(bucketName);
     request.setCannedAcl(cannedAcl);
     nosClient.createBucket(request);

後麵的使用指南隻以其中的一種傳參方式作為例子。

關於異常

所有錯誤異常包裝在兩個異常類型中,在調用 Java SDK 接口的時候,捕捉這些異常並打印必要的信息有利於定位問題( ps:在 JAVA SDK 使用指南的簡單示例代碼沒有重複贅述,使用時注意添加)。

    try{
        nosClient.XXX("XXX");
    //捕捉 NOS 服務器異常錯誤
    }catch (ServiceException e1){
        System.out.println("Error Message:    " + e1.getMessage());    //錯誤描述信息
        System.out.println("HTTP Status Code: " + e1.getStatusCode()); //錯誤http狀態碼
        System.out.println("NOS Error Code:   " + e1.getErrorCode());  //NOS 服務器定義錯誤碼
        System.out.println("Error Type:       " + e1.getErrorType());  //NOS 服務器定義錯誤類型
        System.out.println("Request ID:       " + e1.getRequestId());  //請求 ID,非常重要,有利於對象存儲開發人員跟蹤異常請求的錯誤原因
    //捕捉客戶端錯誤
    }catch(ClientException e2){
        System.out.println("Error Message: " + e2.getMessage());       //客戶端錯誤信息
    }

初始化

1.確定 Endpoint

    目前有效的Endpoint為:nos-eastchina1.126.net

2.獲取密鑰對

使用 NOS-Java-SDK 前,你需要擁有一個有效的 Access Key (包括 Access Key 和 Access Secret )用來進行簽名認證。可以通過如下步驟獲得:

    1)登錄 https://c.163.com/ 注冊用戶

    2)注冊後,蜂巢會頒發 Access Key 和 Secret Key 給客戶,你可以在蜂巢“用戶中心”的“Access Key”查看並管理你的Access Key

3. 在代碼中實例化 NosClient

    import com.netease.cloud.ClientConfiguration;
    import com.netease.cloud.auth.BasicCredentials;
    import com.netease.cloud.auth.Credentials;
    import com.netease.cloud.services.nos.NosClient;
 
    String accessKey = "your-accesskey";
    String secretKey = "your-secretKey ";
    Credentials credentials = new BasicCredentials(accessKey, secretKey);
    NosClient nosClient = new NosClient(credentials);
    nosClient.setEndpoint(endPoint);

注:NosClient是線程安全的,可以並發使用

4. 配置 NosClient 如果你需要修改 NosClient 的默認參數,可以在實例化 NosClient 時傳入 ClientConfiguration 實例。 ClientConfiguration 是 NosClient 的配置類,可配置連接超時、最大連接數等參數。通過 ClientConfiguration 可以設置的參數見下表:

參數 描述 調用方法
connectionTimeout 請求失敗後最大的重試次數
默認:3次
setConnectionTimeout
maxConnections 允許打開的最大HTTP連接數
默認:50
setMaxConnections
socketTimeout Socket層傳輸數據超時時間(單位:毫秒)
默認:50000毫秒
setSocketTimeout
maxErrorRetry 請求失敗後最大的重試次數
默認:3次
setMaxErrorRetry
帶 ClientConfiguration 參數實例化 NosClient 的示例代碼:
    import com.netease.cloud.ClientConfiguration;
    import com.netease.cloud.auth.BasicCredentials;
    import com.netease.cloud.auth.Credentials;
    import com.netease.cloud.services.nos.NosClient;
 
    String accessKey = "your-accesskey";
    String secretKey = "your-secretKey ";
    Credentials credentials = new BasicCredentials(accessKey, secretKey);
    ClientConfiguration conf = new ClientConfiguration();
    // 設置NosClient使用的最大連接數
    conf.setMaxConnections(200);
    // 設置socket超時時間
    conf.setSocketTimeout(10000);
    // 設置失敗請求重試次數
    conf.setMaxErrorRetry(2);
    NosClient nosClient = new NosClient(credentials,conf);
    nosClient.setEndpoint(endPoint);

注意:後麵的示例代碼默認你已經實例化了所需的NosClient對象

桶管理

創建桶

你可以通過 NosClient.createBucket 創建一個桶。示例代碼如下:

    //設置你要創建桶的名稱
    CreateBucketRequest request = new CreateBucketRequest(bucketName);
    //設置桶的權限,如果不設置,默認為Private
    request.setCannedAcl(CannedAccessControlList.PublicRead);
    nosClient.createBucket(request);

注意:

1. 桶的命名規範參見 API 文檔

2. NOS 中的桶名是全局唯一的,你或者他人已經創建了同名桶,你無法再創建該名稱的桶

3. 目前通過 SDK 創建桶可能會有 5 分鍾緩存時間

列舉桶

你可以通過 NosClient.listBuckets 列舉出當前用戶擁有的所有桶。示例代碼如下:

    for (Bucket bucket : nosClient.listBuckets()) {
         System.out.println(" - " + bucket.getName());
    }

刪除桶

你可以通過 NosClient.deleteBucket 刪除指定的桶。示例代碼如下:

nosClient.deleteBucket(bucketName);

注意:

如果指定的桶不為空(桶中有文件或者未完成的分塊上傳),則桶無法刪除;

查看桶是否存在

你可以通過 NosClient.doesBucketExist 查看指定的桶是否存在。示例代碼如下:

boolean exists = nosClient.doesBucketExist(bucketName);

注意:

你或者他人已經創建了指定名稱的桶,doesBucketExist 都會返回 true。否則返回 false

設置桶的ACL

桶的 ACL 包含兩類:Private(私有), PublicRead(公共讀私有寫)。你可以通過 NosClient.setBucketAcl 設置桶的權限。

權限 SDK中的對應值
私有 CannedAccessControlList.Private
公共讀私有寫 CannedAccessControlList.PublicRead

示例代碼如下:

nosClient.setBucketAcl(bucketName, CannedAccessControlList.Private);

查看桶的ACL

你可以通過NosClient.getBucketAcl查看桶的權限。示例代碼如下:

CannedAccessControlList acl = nosClient.getBucketAcl(bucketName);
    // bucket權限
    System.out.println(acl.toString());

文件上傳

在 NOS 中,用戶的每個文件都是一個 Object (對象)。

NOS 提供兩種文件上傳方式:普通上傳(PutObject),上傳小於或等於 100M 的文件;分塊上傳(MultiUpload),大文件可以采用該方式上傳。

NOS Java SDK 提供了豐富的文件上傳接口與功能,主要有:

  • 本地文件普通上傳
  • 支持上傳文件時設置文件元數據信息
  • 流式上傳
  • 分塊上傳

本地文件普通上傳

對於小對象可以使用 putObject 接口進行上傳,putObject 上傳支持的最大文件大小為100M,如果上傳大於100M的文件需要使用分塊上傳。本地文件普通上傳的示例代碼如下:\

    //要上傳文件的路徑
    String filePath = "your-local-file-path";
    try {
       nosClient.putObject("your-bucketname","your-objectname", new File(filePath));
    }catch (Exception e){
       System.out.println(e.getMessage());
    }

上傳文件時設置文件元數據信息

你可以在上傳文件時設置文件元數據信息。可以設置的元數據主要有文件的Content-Type和用戶自定義元數據信息。 這裏以普通上傳為例:

   String filePath = "your-local-file-path";
   ObjectMetadata objectMetadata = new ObjectMetadata();
   //設置Content-Type
   objectMetadata.setContentType("application/xml");
   //設置用戶自定義元數據信息
   Map<String, String> userMeta = new HashMap<String, String>();
   userMeta.put("ud", "test");
   objectMetadata.setUserMetadata(userMeta);
   PutObjectRequest putObjectRequest = new PutObjectRequest("your-bucketname","your-objectname", new File(filePath));
   putObjectRequest.setMetadata(objectMetadata);
   nosClient.putObject(putObjectRequest);

流式上傳

   try {
      ObjectMetadata objectMetadata = new ObjectMetadata();
      //設置流的長度,你還可以設置其他文件元數據信息
      objectMetadata.setContentLength(streamLength);
      nosClient.putObject("your-bucketname","your-objectname", inputStream, objectMetadata)
   }catch (Exception e){
      System.out.println(e.getMessage());
   }

分塊上傳

對於大於 100M 的對象必須進行分塊上傳,分塊上傳的最小單位單位為 16K ,最後一塊可以小於 16K,最大單位為 100M,較大文件使用分塊上傳失敗的代價比較小,隻需要重新上傳失敗的分塊即可; 在文件已經全部存在情況下可以進行分塊並發上傳。

  • 初始化分塊上傳
    //初始化一個分塊上傳,獲取分塊上傳ID,桶名 + 對像名 + 分塊上傳ID 唯一確定一個分塊上傳
    is = new FileInputStream("youFilePath");
    InitiateMultipartUploadRequest  initRequest = new InitiateMultipartUploadRequest("your-bucketname", "your-objectname");
    //你還可以在初始化分塊上傳時,設置文件的Content-Type
    ObjectMetadata objectMetadata = new ObjectMetadata();
    objectMetadata.setContentType("application/xml");
    initRequest.setObjectMetadata(objectMetadata);
    InitiateMultipartUploadResult initResult = nosClient.initiateMultipartUpload(initRequest);
    String uploadId = initResult.getUploadId();
  • 進行分塊上傳

下麵是順序上傳所有分塊的示例,你也可以進行並發上傳。

     //分塊上傳的最小單位為16K,最後一塊可以小於16K,每個分塊都得標識一個唯一的分塊partIndex
     while ((readLen = is.read(buffer, 0, buffSize)) != -1 ){
       InputStream partStream = new ByteArrayInputStream(buffer);
       nosClient.uploadPart(new UploadPartRequest().withBucketName("your-bucketname")
                .withUploadId(uploadId).withInputStream(partStream)
                .withKey("you-objectname").withPartSize(readLen).withPartNumber(partIndex));
       partIndex++;
     }
  • 列出所有分塊
    //這裏可以檢查分塊是否全部上傳,分塊MD5是否與本地計算相符,如果不符或者缺少可以重新上傳

    List<PartETag> partETags = new ArrayList<PartETag>();

    int nextMarker = 0;
    while (true) {
       ListPartsRequest listPartsRequest = new ListPartsRequest("your-bucketname", 
                                                     "your-objectname", uploadId);
       listPartsRequest.setPartNumberMarker(nextMarker);

       PartListing partList = nosClient.listParts(listPartsRequest);

       for (PartSummary ps : partList.getParts()) {
           nextMarker++;
           partETags.add(new PartETag(ps.getPartNumber(), ps.getETag()));
       }

       if (!partList.isTruncated()) {
           break;
       }
    }
  • 完成分塊上傳
   CompleteMultipartUploadRequest completeRequest =  new CompleteMultipartUploadRequest(
                             "your-bucketname","your-objectname", uploadId, partETags);
   CompleteMultipartUploadResult completeResult = nosClient.completeMultipartUpload(completeRequest);

文件下載

你可以通過指定桶名和對象名調用 getObject 接口進行文件下載。NOS Java SDK 提供了如下下載方式:

  • 流式下載
  • 下載到本地文件
  • Range下載
  • 指定If-Modified-Since進行下載

流式下載

   NOSObject nosObject = nosClient.getObject("your-bucketname","your-objectname");
   //可以通過NOSObject對象的getObjectMetadata方法獲取對象的ContentType等元數據信息
   String contentType = nosObject.getObjectMetadata().getContentType();
   //流式獲取文件內容
   InputStream in = nosObject.getObjectContent();
   BufferedReader reader = new BufferedReader(new InputStreamReader(in));
   while (true) {
     String line;
     try {
       line = reader.readLine();
       if (line == null) break;
         System.out.println("\n" + line);
     } catch (IOException e) {
       e.printStackTrace();
     }
   }
   try {
     reader.close();
   } catch (IOException e) {
     e.printStackTrace();
   }

注意:

NosClient.getObjec t獲取的流一定要顯式的 close,否則會造成資源泄露。

下載到本地文件

你可以通過調用 NOS Java SDK 的 getObject 接口直接將 NOS 中的對象下載到本地文件

   String destinationFile = "your-local-filepath";
   GetObjectRequest getObjectRequest = new GetObjectRequest("your-bucketname","your-objectname");
   ObjectMetadata objectMetadata = nosClient.getObject(getObjectRequest, new File(destinationFile));

Range 下載

NOS Java SDK 支持範圍( Range )下載,即下載指定對象的指定範圍的數據。

   GetObjectRequest getObjectRequest = new GetObjectRequest("your-bucketname","your-objectname");
   getObjectRequest.setRange(0, 100);
   NOSObject nosObject = nosClient.getObject(getObjectRequest);
   BufferedReader reader = new BufferedReader(new InputStreamReader(in));
   while (true) {
     String line;
     try {
       line = reader.readLine();
       if (line == null) break;
         System.out.println("\n" + line);
     } catch (IOException e) {
       e.printStackTrace();
     }
   }
   try {
     reader.close();
   } catch (IOException e) {
     e.printStackTrace();
   }

指定 If-Modified-Since 進行下載

下載文件時,你可以指定 If-Modified-Since 參數,滿足文件的最後修改時間小於等於 If-Modified-Since 參數指定的時間,則不進行下載,否則正常下載文件。

   //假設需要下載的文件的最後修改時間為: Date lastModified;
   //lastModified小於等於指定If-Modified-Since參數
   GetObjectRequest getObjectRequest = new GetObjectRequest("your-bucketname","your-objectname");
   Date afterTime = new Date(lastModified.getTime() + 1000);
   getObjectRequest.setModifiedSinceConstraint(afterTime);
   //此時nosObject等於null
   NOSObject nosObject = client.getObject(getObjectRequest);
   Date beforeTime = new Date(lastModified.getTime() -1000);
   getObjectRequest.setModifiedSinceConstraint(beforeTime);
   //此時nosObject不等於null,可以正常獲取文件內容
   nosObject = client.getObject(getObjectRequest);
   BufferedReader reader = new BufferedReader(new InputStreamReader(in));
   while (true) {
     String line;
     try {
       line = reader.readLine();
       if (line == null) break;
         System.out.println("\n" + line);
     } catch (IOException e) {
       e.printStackTrace();
     }
   }
   try {
     reader.close();
   } catch (IOException e) {
     e.printStackTrace();
   }

文件管理

你可以通過 NOS Java SDK 進行如下文件管理操作:

  • 判斷文件是否存在
  • 文件刪除
  • 獲取文件元數據信息
  • 文件複製(copy)
  • 文件重命名(move)
  • 列舉桶內文件
  • 生成私有對象可下載的URL連接

判斷文件是否存在

你可以通過 NosClient.doesObjectExist 判斷文件是否存在。

   boolean isExist = nosClient.doesObjectExist("your-bucketname","your-objectname");

文件刪除

你可以通過 NOSClient.deleteObject 刪除單個文件

   nosClient.deleteObject("your-bucketname","your-objectname");

你還可以通過 NOSClient.deleteObjects 一次刪除多個文件

   try {
       DeleteObjectsResult result = nosClient.deleteObjects(deleteObjectsRequest);
       List<DeletedObject>  deleteObjects = result.getDeletedObjects();
       //print the delete results
       for (DeletedObject items: deleteObjects){
         System.out.println(items.getKey());
       }
   // 部分對象刪除失敗
   } catch (MultiObjectDeleteException e) { 
       List<DeleteError> deleteErrors = e.getErrors();
       for (DeleteError error : deleteErrors) {
           System.out.println(error.getKey());
       }
   } catch (ServiceException  e) {
           //捕捉nos服務器異常錯誤
   } catch (ClientException ace) {
          //捕捉客戶端錯誤
   }

獲取文件元數據信息

你可以通過 NOSClient.getObjectMetadata 獲取文件元數據信息

   nosClient.getObjectMetadata("your-bucketname","your-objectname");

文件複製(copy)

你可以通過 NOSClient.copyObject 接口實現文件拷貝功能。 NOS 支持桶內 copy 以及相同用戶的跨桶 copy 。

   nosClient.copyObject("source-bucket", "source-object", "dst-bucket", "dst-object");

文件重命名(move)

你可以通過 NOSClient.moveObject 接口實現文件重命名功能。 NOS 僅支持桶內 move 。

   nosClient.moveObject("bucket-name", "source-object-key", "bucket-name", "dst-object-key");

列舉桶內文件

你可以通過 NOSClient.listObjects 列出桶裏的文件。listObjects 接口如果調用成功,會返回一個 ObjectListing 對象,列舉的結果保持在該對象中。

ObjectListing 的具體信息如下表所示:

方法 含義
List<NOSObjectSummary> getObjectSummaries() 返回的文件列表(包含文件的名稱、Etag的元數據信息)
String getPrefix() 本次查詢的文件名前綴
String getDelimiter() 文件分界符
String getMarker() 這次List Objects的起點
int getMaxKeys() 響應請求內返回結果的最大數目
String getNextMarker() 下一次List Object的起點
boolean isTruncated() 是否截斷,如果因為設置了limit導致不是所有的數據集都返回,則該值設置為true
List<String> getCommonPrefixes() 如果請求中指定了delimiter參數,則返回的包含CommonPrefixes元素。該元素標明以delimiter結尾,並有共同前綴的對象的集合

NOSClient.listObjects 接口提供兩種調用方式:簡單列舉、通過 ListObjectsRequest 列舉

簡單列舉

簡單列舉隻需指定需要列舉的桶名,最多返回100條對象記錄,建議桶內對象數較少時(小於100)使用。

   ObjectListing objectListing = nosClient.listObjects("your-bucketname");
   List<NOSObjectSummary> sums = objectListing.getObjectSummaries();
   for (NOSObjectSummary s : sums) {
     System.out.println("\t" + s.getKey());
   }

通過ListObjectsRequest列舉

你還可以通過設置 ListObjectsReques 參數實現各種靈活的查詢功能。ListObjectsReques 的可設置的參數如下:

設置方法 作用
setPrefix(String prefix) 限定返回的object key必須以prefix作為前綴
setDelimiter(String delimiter) 是一個用於對 Object 名字進行分組的字符。所有名字包含指定的前綴且第一次出現 delimiter 字符之間的 object作為一組元素—— CommonPrefixes
setMarker(String marker) 字典序的起始標記,隻列出該標記之後的部分
setMaxKeys(Integer maxKeys) 限定返回的數量,返回的結果小於或等於該值(默認值為100)
分頁列舉桶內的所有文件
   List<NOSObjectSummary> listResult = new ArrayList<NOSObjectSummary>();
   ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
   listObjectsRequest.setBucketName("your-bucketname");
   listObjectsRequest.setMaxKeys(50);
   ObjectListing listObjects = nosClient.listObjects(listObjectsRequest);
   do {
     listResult.addAll(listObjects.getObjectSummaries());
     if (listObjects.isTruncated()) {
       ListObjectsRequest request = new ListObjectsRequest();
       request.setBucketName(listObjectsRequest.getBucketName());
       request.setMarker(listObjects.getNextMarker());
       listObjects =  nosClient.listObjects(request);
     } else {
       break;
     }
   } while (listObjects != null);
使用Delimiter模擬文件夾功能

假設桶內有如下對象:a/1.jpg、a/2.jpg、a/b/1.txt、a/b/2.txt,列舉a文件夾下的文件及子文件夾的示例代碼如下:

   ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
   listObjectsRequest.setBucketName("your-bucketname");
   listObjectsRequest.setDelimiter("/");
   listObjectsRequest.setPrefix("a/");
   ObjectListing listing = nosClient.listObjects(listObjectsRequest);
   // 遍曆所有Object
   System.out.println("Objects:");
   for (NOSObjectSummary objectSummary : listing.getObjectSummaries()) {
       System.out.println(objectSummary.getKey());
   }
   // 遍曆所有CommonPrefix
   System.out.println("CommonPrefixs:");
   for (String commonPrefix : listing.getCommonPrefixes()) {
       System.out.println(commonPrefix);
   }

示例代碼的輸出如下:

Objects:

a/1.jpg

a/2.jpg

CommonPrefixs:

a/b/

生成私有對象可下載的URL鏈接

NOS Java SDK 支持生成可下載私有對象的 URL 連接,你可以將該鏈接提供給第三方進行文件下載:

   Credentials credentials;
   credentials = new BasicCredentials(accessKey, secretKey);
   NosClient client = new NosClient(credentials);
   // 配置client
   String bucketName = "your-bucketname";
   String key = "object-name";
   GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, key);
   generatePresignedUrlRequest.setExpiration(new Date(System.currentTimeMillis()+3600*1000*24));
   // 設置可下載URL的過期時間為1天後
   URL url = nosClient.generatePresignedUrl(generatePresignedUrlRequest);
   System.out.println(url);

文件上傳下載工具類:TransferManager

前文提到的是 NOS Java SDK 提供的基礎接口,為方便用戶進行文件上傳下載,NOS Java SDK 提供了封裝更好、使用更方便的工具類:TransferManager。

TransferManager的初始化

   //先實例化一個NosClient
   String accessKey = "your-accesskey";
   String secretKey = "your-secretKey ";
   Credentials credentials = new BasicCredentials(accessKey, secretKey);
   NosClient nosClient = new NosClient(credentials);
   nosClient.setEndpoint(endPoint);
   //然後通過nosClient對象來初始化TransferManager
   TransferManager transferManager = new TransferManager(nosClient);

使用TransferManager進行文件上傳

TransferManager 會根據文件大小,選擇是否進行分塊上傳。當文件小於等於 16M 時,TransferManager 會自動調用 PutObject 接口,否則 TransferManager 會自動對文件進行分塊上傳。 1、上傳本地文件:

如果指定上傳的本地文件大於 16M,TransferManager 會自動對文件進行分塊,並發調用分塊上傳接口進行上傳,大大提高上傳文件的速度。

   //上傳文件
   Upload upload = transferManager.upload("your-bucketname", "your-objectname", new File("your-file"));
   UploadResult  result = upload.waitForUploadResult();

2、流式上傳:

你也可以使用 TransferManager 進行流式上傳,但是相比本地文件上傳,流式上傳無法做到多個分塊並發上傳,隻能一個分塊一個分塊順序上傳。

注意: 如果你調用 TransferManager 流式上傳的文件大於 100M,必須指定對象的 ContentLength

   //流式上傳文件
   ObjectMetadata objectMetadata = new ObjectMetadata();
   objectMetadata.setContentLength(file.length());
   Upload upload = transferManager.upload("your-bucketname", "your-objectname", inputStream, objectMetadata);
   UploadResult  result = upload.waitForUploadResult();

3、上傳目錄

你可以使用 TransferManager 將某個目錄下的文件全部上傳到 NOS ,對象名即文件名,不支持多級目錄

   MultipleFileUpload result = transferManager.uploadDirectory("your-buckename", null, new File("dirPath"), false);
   result.waitForCompletion();

4、下載文件

   File file = new  File("your-destFile");
   Download download = transferManager.download("your-bucketname", "your-objectname", file);
   download.waitForCompletion();

最後更新:2017-01-03 10:48:53

  上一篇:go 青海地區管局規則
  下一篇:go 密鑰API