日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

Android分片上傳

更新時(shí)間:

OSS提供的分片上傳(Multipart Upload)功能,將要上傳的較大文件(Object)分成多個(gè)分片(Part)來分別上傳,上傳完成后再調(diào)用CompleteMultipartUpload接口將這些Part組合成一個(gè)Object來達(dá)到斷點(diǎn)續(xù)傳的效果。

注意事項(xiàng)

分片上傳流程

分片上傳(Multipart Upload)分為以下三個(gè)步驟:

  1. 初始化一個(gè)分片上傳事件。

    調(diào)用oss.initMultipartUpload方法返回OSS創(chuàng)建的全局唯一的uploadId。

  2. 上傳分片。

    調(diào)用oss.uploadPart方法上傳分片數(shù)據(jù)。

    說明
    • 對于同一個(gè)uploadId,分片號(PartNumber)標(biāo)識了該分片在整個(gè)文件內(nèi)的相對位置。如果使用同一個(gè)分片號上傳了新的數(shù)據(jù),則OSS上該分片已有的數(shù)據(jù)將會被覆蓋。

    • OSS將收到的分片數(shù)據(jù)的MD5值放在ETag頭內(nèi)返回給用戶。

    • OSS計(jì)算上傳數(shù)據(jù)的MD5值,并與SDK計(jì)算的MD5值比較,如果不一致則返回InvalidDigest錯(cuò)誤碼。

  3. 完成分片上傳。

    所有分片上傳完成后,調(diào)用oss.CompleteMultipartUpload方法將所有Part合并成完整的文件。

分片上傳完整示例

以下通過一個(gè)完整的示例對分片上傳的流程進(jìn)行逐步解析:

// 填寫B(tài)ucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫本地文件完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";

// 初始化分片上傳。
InitiateMultipartUploadRequest init = new InitiateMultipartUploadRequest(bucketName, objectName);
InitiateMultipartUploadResult initResult = oss.initMultipartUpload(init);
// 返回uploadId。
String uploadId = initResult.getUploadId();
// 根據(jù)uploadId執(zhí)行取消分片上傳事件或者列舉已上傳分片的操作。
// 如果您需要根據(jù)您需要uploadId執(zhí)行取消分片上傳事件的操作,您需要在調(diào)用InitiateMultipartUpload完成初始化分片之后獲取uploadId。 
// 如果您需要根據(jù)您需要uploadId執(zhí)行列舉已上傳分片的操作,您需要在調(diào)用InitiateMultipartUpload完成初始化分片之后,且在調(diào)用CompleteMultipartUpload完成分片上傳之前獲取uploadId。
// Log.d("uploadId", uploadId);

// 設(shè)置單個(gè)Part的大小,單位為字節(jié),取值范圍為100 KB~5 GB。
int partCount = 100 * 1024;
// 分片上傳。
List<PartETag> partETags = new ArrayList<>();
for (int i = 1; i < 5; i++) {
    byte[] data = new byte[partCount];

    RandomAccessFile raf = new RandomAccessFile(localFilepath, "r");
    long skip = (i-1) * partCount;
    raf.seek(skip);
    raf.readFully(data, 0, partCount);

    UploadPartRequest uploadPart = new UploadPartRequest();
    uploadPart.setBucketName(bucketName);
    uploadPart.setObjectKey(objectName);
    uploadPart.setUploadId(uploadId);
    // 設(shè)置分片號,從1開始標(biāo)識。每一個(gè)上傳的Part都有一個(gè)分片號,取值范圍是1~10000。
    uploadPart.setPartNumber(i); 
    uploadPart.setPartContent(data);
    try {
        UploadPartResult result = oss.uploadPart(uploadPart);
        PartETag partETag = new PartETag(uploadPart.getPartNumber(), result.getETag());
        partETags.add(partETag);
    } catch (ServiceException serviceException) {
        OSSLog.logError(serviceException.getErrorCode());
    }
}
Collections.sort(partETags, new Comparator<PartETag>() {
    @Override
    public int compare(PartETag lhs, PartETag rhs) {
        if (lhs.getPartNumber() < rhs.getPartNumber()) {
            return -1;
        } else if (lhs.getPartNumber() > rhs.getPartNumber()) {
            return 1;
        } else {
            return 0;
        }
    }
});

// 完成分片上傳。
CompleteMultipartUploadRequest complete = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);

// 上傳回調(diào)。完成分片上傳請求時(shí)可以設(shè)置CALLBACK_SERVER參數(shù),請求完成后會向指定的Server Address發(fā)送回調(diào)請求??赏ㄟ^返回結(jié)果的completeResult.getServerCallbackReturnBody()查看servercallback結(jié)果。
complete.setCallbackParam(new HashMap<String, String>() {
    {
        put("callbackUrl", CALLBACK_SERVER); //修改為您的服務(wù)器地址。
        put("callbackBody", "test");
    }
});
CompleteMultipartUploadResult completeResult = oss.completeMultipartUpload(complete);
OSSLog.logError("-------------- serverCallback: " + completeResult.getServerCallbackReturnBody());

上述代碼調(diào)用uploadPart來上傳每一個(gè)Part。

  • 每一個(gè)分片上傳請求均需指定uploadIdPartNumber。PartNumber的范圍是1~10000。如果超出該范圍,OSS將返回InvalidArgument的錯(cuò)誤碼。

  • uploadPart要求除最后一個(gè)Part外,其他的Part大小都要大于100 KB。uploadPart僅在完成分片上傳時(shí)校驗(yàn)Part的大小。

  • 每次上傳Part時(shí)都要將流定位至此次上傳片開頭所對應(yīng)的位置。

  • 每次上傳Part之后,OSS的返回結(jié)果會包含一個(gè)PartETag值,ETag值為Part數(shù)據(jù)的MD5值,您需要將ETag值和塊編號組合成PartEtag并保存,用于后續(xù)完成分片上傳。

本地文件分片上傳

您可以通過同步方式或者異步方式分片上傳本地文件到OSS。

說明

分片上傳完整示例是按照分片上傳流程逐步實(shí)現(xiàn)的完整代碼,本地文件分片上傳的代碼是將分片上傳完整示例中的代碼進(jìn)行了封裝,您只需要使用MultipartUploadRequest即可實(shí)現(xiàn)分片上傳。

  • 調(diào)用同步接口分片上傳本地文件

    以下代碼用于以同步方式分片上傳examplefile.txt文件到目標(biāo)存儲空間examplebucketexampledir目錄下的exampleobject.txt文件。

    // 填寫Bucket名稱,例如examplebucket。
    String bucketName = "examplebucket";
    // 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
    String objectName = "exampledir/exampleobject.txt";
    // 填寫本地文件完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
    String localFilepath = "/storage/emulated/0/oss/examplefile.txt";
    
    ObjectMetadata meta = new ObjectMetadata();
    // 設(shè)置文件元數(shù)據(jù)等。
    meta.setHeader("x-oss-object-acl", "public-read-write");
    MultipartUploadRequest rq = new MultipartUploadRequest(bucketName, objectName, localFilepath, meta);
    // 設(shè)置PartSize。PartSize默認(rèn)值為256 KB,最小值為100 KB。
    rq.setPartSize(1024 * 1024);
    rq.setProgressCallback(new OSSProgressCallback<MultipartUploadRequest>() {
        @Override
        public void onProgress(MultipartUploadRequest request, long currentSize, long totalSize) {
            OSSLog.logDebug("[testMultipartUpload] - " + currentSize + " " + totalSize, false);
        }
    });
    
    CompleteMultipartUploadResult result = oss.multipartUpload(rq);

    對于Android10及之后版本的分區(qū)存儲,您可以使用文件的Uri上傳文件到OSS。

    // 填寫Bucket名稱,例如examplebucket。
    String bucketName = "examplebucket";
    // 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
    String objectName = "exampledir/exampleobject.txt";
    
    ObjectMetadata meta = new ObjectMetadata();
    // 設(shè)置文件元數(shù)據(jù)等。
    meta.setHeader("x-oss-object-acl", "public-read-write");
    MultipartUploadRequest rq = new MultipartUploadRequest(bucketName, objectName, fileUri, meta);
    // 設(shè)置PartSize。PartSize默認(rèn)值為256 KB,最小值為100 KB。
    rq.setPartSize(1024 * 1024);
    rq.setProgressCallback(new OSSProgressCallback<MultipartUploadRequest>() {
        @Override
        public void onProgress(MultipartUploadRequest request, long currentSize, long totalSize) {
            OSSLog.logDebug("[testMultipartUpload] - " + currentSize + " " + totalSize, false);
        }
    });
    
    CompleteMultipartUploadResult result = oss.multipartUpload(rq);
  • 調(diào)用異步接口分片上傳本地文件

    以下代碼用于以異步方式分片上傳examplefile.txt文件到目標(biāo)存儲空間examplebucketexampledir目錄下的exampleobject.txt文件。

    // 填寫Bucket名稱,例如examplebucket。
    String bucketName = "examplebucket";
    // 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
    String objectName = "exampledir/exampleobject.txt";
    // 填寫本地文件完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
    String localFilepath = "/storage/emulated/0/oss/examplefile.txt";
    
    MultipartUploadRequest request = new MultipartUploadRequest(bucketName, objectName, localFilepath);
    
    request.setProgressCallback(new OSSProgressCallback<MultipartUploadRequest>() {
        @Override
        public void onProgress(MultipartUploadRequest request, long currentSize, long totalSize) {
            OSSLog.logDebug("[testMultipartUpload] - " + currentSize + " " + totalSize, false);
        }
    });
    
    OSSAsyncTask task = oss.asyncMultipartUpload(request, new OSSCompletedCallback<MultipartUploadRequest, CompleteMultipartUploadResult>() {
        @Override
        public void onSuccess(MultipartUploadRequest request, CompleteMultipartUploadResult result) {
            OSSLog.logInfo(result.getServerCallbackReturnBody());
        }
    
        @Override
        public void onFailure(MultipartUploadRequest request, ClientException clientException, ServiceException serviceException) {
            OSSLog.logError(serviceException.getRawMessage());
        }
    });
    
    //Thread.sleep(100);
    // 取消分片上傳。
    //task.cancel();   
    
    task.waitUntilFinished();

    對于Android10及之后版本的分區(qū)存儲,您可以使用文件的Uri上傳文件到OSS。

    // 填寫Bucket名稱,例如examplebucket。
    String bucketName = "examplebucket";
    // 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
    String objectName = "exampledir/exampleobject.txt";
    
    MultipartUploadRequest request = new MultipartUploadRequest(bucketName, objectName, fileUri);
    
    request.setProgressCallback(new OSSProgressCallback<MultipartUploadRequest>() {
        @Override
        public void onProgress(MultipartUploadRequest request, long currentSize, long totalSize) {
            OSSLog.logDebug("[testMultipartUpload] - " + currentSize + " " + totalSize, false);
        }
    });
    
    OSSAsyncTask task = oss.asyncMultipartUpload(request, new OSSCompletedCallback<MultipartUploadRequest, CompleteMultipartUploadResult>() {
        @Override
        public void onSuccess(MultipartUploadRequest request, CompleteMultipartUploadResult result) {
            OSSLog.logInfo(result.getServerCallbackReturnBody());
        }
    
        @Override
        public void onFailure(MultipartUploadRequest request, ClientException clientException, ServiceException serviceException) {
            OSSLog.logError(serviceException.getRawMessage());
        }
    });
    
    //Thread.sleep(100);
    // 取消分片上傳。
    //task.cancel();   
    
    task.waitUntilFinished();

列舉已上傳分片

調(diào)用oss.listParts方法獲取某個(gè)上傳事件所有已上傳的分片。

以下代碼用于列舉已上傳分片。

// 填寫B(tài)ucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫uploadId。uploadId來源于調(diào)用InitiateMultipartUpload完成初始化分片之后,且在調(diào)用CompleteMultipartUpload完成分片上傳之前的返回結(jié)果。
String uploadId = "0004B999EF518A1FE585B0C9****";

// 列舉分片。
ListPartsRequest listParts = new ListPartsRequest(bucketName, objectName, uploadId);
ListPartsResult result = oss.listParts(listParts);

List<PartETag> partETagList = new ArrayList<PartETag>();
for (PartSummary part : result.getParts()) {
    partETagList.add(new PartETag(part.getPartNumber(), part.getETag()));
}
重要

默認(rèn)情況下,如果存儲空間中的分片上傳事件的數(shù)量大于1000,則OSS僅返回1000個(gè)Multipart Upload信息,且返回結(jié)果中IsTruncated的值為false,并返回NextPartNumberMarker作為下次讀取的起點(diǎn)。

取消分片上傳事件

調(diào)用oss.abortMultipartUpload方法來取消分片上傳事件。當(dāng)一個(gè)分片上傳事件被取消后,無法再使用該uploadId進(jìn)行任何操作,已上傳的分片數(shù)據(jù)會被刪除。

以下代碼用于取消分片上傳事件。

// 填寫B(tài)ucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫uploadId。uploadId來源于調(diào)用InitiateMultipartUpload完成初始化分片之后的返回結(jié)果。
String uploadId = "0004B999EF518A1FE585B0C9****";

// 取消分片上傳。
AbortMultipartUploadRequest abort = new AbortMultipartUploadRequest(bucketName, objectName, uploadId);
AbortMultipartUploadResult abortResult = oss.abortMultipartUpload(abort);

相關(guān)文檔

  • 關(guān)于分片上傳的完整示例代碼,請參見GitHub示例。

  • 分片上傳的完整實(shí)現(xiàn)涉及三個(gè)API接口,詳情如下:

  • 關(guān)于取消分片上傳事件的API接口說明,請參見AbortMultipartUpload。

  • 關(guān)于列舉已上傳分片的API接口說明,請參見ListParts。

  • 關(guān)于列舉所有執(zhí)行中的分片上傳事件(即已初始化但尚未完成或已取消的分片上傳事件)的API接口說明,請參見ListMultipartUploads。

  • 關(guān)于初始化OSSClient,請參見如何初始化AndroidOSSClient實(shí)例