spring boot使用阿里雲分片上傳講解示例
阿新 • • 發佈:2022-12-02
import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.*; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class Demo { public static void main(String[] args) throws Exception { // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 阿里雲賬號AccessKey擁有所有API的訪問許可權,風險很高。強烈建議您建立並使用RAM使用者進行API訪問或日常運維,請登入RAM控制檯建立RAM使用者。 String accessKeyId = "yourAccessKeyId"; String accessKeySecret = "yourAccessKeySecret"; // 填寫Bucket名稱,例如examplebucket。 String bucketName = "examplebucket"; // 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。 String objectName = "exampledir/exampleobject.txt"; // 建立OSSClient例項。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); try { // 建立InitiateMultipartUploadRequest物件。 InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName); // 如果需要在初始化分片時設定請求頭,請參考以下示例程式碼。 // ObjectMetadata metadata = new ObjectMetadata(); // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString()); // 指定該Object的網頁快取行為。 // metadata.setCacheControl("no-cache"); // 指定該Object被下載時的名稱。 // metadata.setContentDisposition("attachment;filename=oss_MultipartUpload.txt"); // 指定該Object的內容編碼格式。 // metadata.setContentEncoding(OSSConstants.DEFAULT_CHARSET_NAME); // 指定初始化分片上傳時是否覆蓋同名Object。此處設定為true,表示禁止覆蓋同名Object。 // metadata.setHeader("x-oss-forbid-overwrite", "true"); // 指定上傳該Object的每個part時使用的伺服器端加密方式。 // metadata.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION); // 指定Object的加密演算法。如果未指定此選項,表明Object使用AES256加密演算法。 // metadata.setHeader(OSSHeaders.OSS_SERVER_SIDE_DATA_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION); // 指定KMS託管的使用者主金鑰。 // metadata.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION_KEY_ID, "9468da86-3509-4f8d-a61e-6eab1eac****"); // 指定Object的儲存型別。 // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard); // 指定Object的物件標籤,可同時設定多個標籤。 // metadata.setHeader(OSSHeaders.OSS_TAGGING, "a:1"); // request.setObjectMetadata(metadata); // 初始化分片。 InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request); // 返回uploadId,它是分片上傳事件的唯一標識。您可以根據該uploadId發起相關的操作,例如取消分片上傳、查詢分片上傳等。 String uploadId = upresult.getUploadId(); // partETags是PartETag的集合。PartETag由分片的ETag和分片號組成。 List<PartETag> partETags = new ArrayList<PartETag>(); // 每個分片的大小,用於計算檔案有多少個分片。單位為位元組。 final long partSize = 1 * 1024 * 1024L; //1 MB。 // 填寫本地檔案的完整路徑。如果未指定本地路徑,則預設從示例程式所屬專案對應本地路徑中上傳檔案。 final File sampleFile = new File("D:\\localpath\\examplefile.txt"); long fileLength = sampleFile.length(); int partCount = (int) (fileLength / partSize); if (fileLength % partSize != 0) { partCount++; } // 遍歷分片上傳。 for (int i = 0; i < partCount; i++) { long startPos = i * partSize; long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize; InputStream instream = new FileInputStream(sampleFile); // 跳過已經上傳的分片。 instream.skip(startPos); UploadPartRequest uploadPartRequest = new UploadPartRequest(); uploadPartRequest.setBucketName(bucketName); uploadPartRequest.setKey(objectName); uploadPartRequest.setUploadId(uploadId); uploadPartRequest.setInputStream(instream); // 設定分片大小。除了最後一個分片沒有大小限制,其他的分片最小為100 KB。 uploadPartRequest.setPartSize(curPartSize); // 設定分片號。每一個上傳的分片都有一個分片號,取值範圍是1~10000,如果超出此範圍,OSS將返回InvalidArgument錯誤碼。 uploadPartRequest.setPartNumber( i + 1); // 每個分片不需要按順序上傳,甚至可以在不同客戶端上傳,OSS會按照分片號排序組成完整的檔案。 UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest); // 每次上傳分片之後,OSS的返回結果包含PartETag。PartETag將被儲存在partETags中。 partETags.add(uploadPartResult.getPartETag()); } // 建立CompleteMultipartUploadRequest物件。 // 在執行完成分片上傳操作時,需要提供所有有效的partETags。OSS收到提交的partETags後,會逐一驗證每個分片的有效性。當所有的資料分片驗證通過後,OSS將把這些分片組合成一個完整的檔案。 CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags); // 如果需要在完成分片上傳的同時設定檔案訪問許可權,請參考以下示例程式碼。 // completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.Private); // 指定是否列舉當前UploadId已上傳的所有Part。如果通過服務端List分片資料來合併完整檔案時,以上CompleteMultipartUploadRequest中的partETags可為null。 // Map<String, String> headers = new HashMap<String, String>(); // 如果指定了x-oss-complete-all:yes,則OSS會列舉當前UploadId已上傳的所有Part,然後按照PartNumber的序號排序並執行CompleteMultipartUpload操作。 // 如果指定了x-oss-complete-all:yes,則不允許繼續指定body,否則報錯。 // headers.put("x-oss-complete-all","yes"); // completeMultipartUploadRequest.setHeaders(headers); // 完成分片上傳。 CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest); System.out.println(completeMultipartUploadResult.getETag()); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } }