全部產品
Search
文件中心

Object Storage Service:Android禁止覆蓋同名檔案

更新時間:Feb 28, 2024

預設情況下,如果新添加檔案(Object)與現有檔案同名且對該檔案有存取權限,則新添加的檔案將覆蓋原有的檔案。本文介紹如何通過佈建要求頭x-oss-forbid-overwrite在簡單上傳、拷貝檔案及分區上傳等情境中禁止覆蓋同名檔案。

注意事項

簡單上傳

以下代碼用於簡單上傳時禁止覆蓋同名檔案:

// 填寫Bucket名稱,例如examplebucket。關於Bucket名稱命名規範的更多資訊,請參見Bucket。
String bucketName = "examplebucket";
// 填寫不包含Bucket名稱在內的Object完整路徑,例如exampledir/exampleobject.txt。有關Object名稱命名規範的更多資訊,請參見Object。
String objectKey = "exampledir/exampleobject.txt";
// 填寫待上傳的本地檔案所在的完整路徑。
String localFile = "/storage/emulated/0/oss/examplefile.txt";
// 構造上傳請求。
PutObjectRequest put = new PutObjectRequest(bucketName, objectKey, localFile);
ObjectMetadata metadata = new ObjectMetadata();

// 指定上傳檔案操作時是否覆蓋同名Object。
// 不指定x-oss-forbid-overwrite時,預設覆蓋同名Object。
// 指定x-oss-forbid-overwrite為false時,表示允許覆蓋同名Object。
// 指定x-oss-forbid-overwrite為true時,表示禁止覆蓋同名Object,如果同名Object已存在,程式將報錯。
metadata.setHeader("x-oss-forbid-overwrite", "true");
put.setMetadata(metadata);

OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
    @Override
    public void onSuccess(PutObjectRequest request, PutObjectResult result) {
        Log.d("PutObject", "UploadSuccess");
        Log.d("ETag", result.getETag());
        Log.d("RequestId", result.getRequestId());
    }

    @Override
    public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // 請求異常。
        if (clientExcepion != null) {
            // 用戶端異常,例如網路異常等。
            clientExcepion.printStackTrace();
        }
        if (serviceException != null) {
            // 服務端異常。
            Log.e("ErrorCode", serviceException.getErrorCode());
            Log.e("RequestId", serviceException.getRequestId());
            Log.e("HostId", serviceException.getHostId());
            Log.e("RawMessage", serviceException.getRawMessage());
        }
    }
});

拷貝檔案

以下代碼用於拷貝檔案時禁止覆蓋同名檔案:

// 填寫源Bucket名稱。
String srcBucketName = "srcbucket";
// 填寫源Bucket內的Object完整路徑。
String srcObjectKey = "dir1/srcobject.txt";
// 填寫目標Bucket名稱。
String destBucketName = "destbucket";
// 填寫目標Bucket內的Object完整路徑。
String destObjectKey = "dir2/destobject.txt";
// 建立Copy請求。
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketName, srcObjectKey, destBucketName, destObjectKey);

ObjectMetadata metadata = new ObjectMetadata();

// 指定拷貝檔案操作時是否覆蓋同名Object。
// 不指定x-oss-forbid-overwrite時,預設覆蓋同名Object。
// 指定x-oss-forbid-overwrite為false時,表示允許覆蓋同名Object。
// 指定x-oss-forbid-overwrite為true時,表示禁止覆蓋同名Object,如果同名Object已存在,程式將報錯。
metadata.setHeader("x-oss-forbid-overwrite", "true");
copyObjectRequest.setNewObjectMetadata(metadata);

// 使用非同步方式拷貝檔案。
OSSAsyncTask copyTask = oss.asyncCopyObject(copyObjectRequest, new OSSCompletedCallback<CopyObjectRequest, CopyObjectResult>() {
    @Override
    public void onSuccess(CopyObjectRequest request, CopyObjectResult result) {
        Log.d("copyObject", "copy success!");
    }

    @Override
    public void onFailure(CopyObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // 請求異常。
        if (clientExcepion != null) {
            // 用戶端異常,例如網路異常等。
            clientExcepion.printStackTrace();
        }
        if (serviceException != null) {
            // 服務異常。
            Log.e("ErrorCode", serviceException.getErrorCode());
            Log.e("RequestId", serviceException.getRequestId());
            Log.e("HostId", serviceException.getHostId());
            Log.e("RawMessage", serviceException.getRawMessage());
        }
    }
});

分區上傳

以下代碼用於分區上傳時禁止覆蓋同名檔案:

// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫不包含Bucket名稱在內的Object完整路徑,例如exampledir/exampleobject.txt。
String objectKey = "exampledir/exampleobject.txt";
// 填寫待上傳的本地檔案所在的完整路徑。
String localFile = "/storage/emulated/0/oss/examplefile.txt";

// 初始化分區上傳。
InitiateMultipartUploadRequest init = new InitiateMultipartUploadRequest(bucketName, objectKey);
ObjectMetadata metadata = new ObjectMetadata();
// 指定上傳檔案操作時是否覆蓋同名Object。
// 不指定x-oss-forbid-overwrite時,預設覆蓋同名Object。
// 指定x-oss-forbid-overwrite為false時,表示允許覆蓋同名Object。
// 指定x-oss-forbid-overwrite為true時,表示禁止覆蓋同名Object,如果同名Object已存在,程式將報錯。
metadata.setHeader("x-oss-forbid-overwrite", "true");
init.setMetadata(metadata);

InitiateMultipartUploadResult initResult = oss.initMultipartUpload(init);
// 返回uploadId。uploadId是分區上傳事件的唯一標識。您可以根據該uploadId發起相關操作,例如取消分區上傳、查詢分區上傳等。
String uploadId = initResult.getUploadId();

// 設定單個Part的大小,單位為位元組,取值範圍為100 KB~5 GB。
int partCount = 100 * 1024;
// 分區上傳。
List<PartETag> partETags = new ArrayList<PartETag>();
for (int i = 1; i < 5; i++) {
    byte[] data = new byte[partCount];

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

    UploadPartRequest uploadPart = new UploadPartRequest();
    uploadPart.setBucketName(bucketName);
    uploadPart.setObjectKey(objectKey);
    uploadPart.setUploadId(uploadId);
    // 設定分區號,從1開始標識。每一個上傳的Part都有一個分區號,取值範圍是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, objectKey, uploadId, partETags);
metadata = new ObjectMetadata();
// 指定完成上傳檔案操作時是否覆蓋同名Object。
// 不指定x-oss-forbid-overwrite時,預設覆蓋同名Object。
// 指定x-oss-forbid-overwrite為false時,表示允許覆蓋同名Object。
// 指定x-oss-forbid-overwrite為true時,表示禁止覆蓋同名Object,如果同名Object已存在,程式將報錯。
metadata.setHeader("x-oss-forbid-overwrite", "true");
complete.setMetadata(metadata);
CompleteMultipartUploadResult completeResult = oss.completeMultipartUpload(complete);           

相關文檔