By default, if you upload an object that has the same name as an existing object on which you have access permissions, the existing object is overwritten by the uploaded object. This topic describes how to configure the x-oss-forbid-overwrite request header to prevent objects from being overwritten by objects with the same names when you copy objects or perform simple upload or multipart upload.

Simple upload

The following code provides an example on how to prevent objects from being overwritten by objects with the same names in simple upload:

// Specify the name of the bucket. Example: examplebucket. For more information about the naming conventions for buckets, see Bucket naming conventions. 
String bucketName = "examplebucket";
// Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: exampledir/exampleobject.txt. For more information about the naming conventions for objects, see Object naming conventions. 
String objectKey = "exampledir/exampleobject.txt";
// Specify the full path of the local file that you want to upload. 
String localFile = "/storage/emulated/0/oss/examplefile.txt";
// Construct a request to upload the local file. 
PutObjectRequest put = new PutObjectRequest(bucketName, objectKey, localFile);
ObjectMetadata metadata = new ObjectMetadata();

// Specify whether to overwrite the object with the same name. 
// By default, if x-oss-forbid-overwrite is not specified, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to false, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to true, existing objects are not overwritten by the objects with the same names. If an existing object has the same name as the uploaded object, an error is reported. 
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) {
        // Handle request exceptions. 
        if (clientExcepion != null) {
            // Handle client-side exceptions such as network errors. 
            clientExcepion.printStackTrace();
        }
        if (serviceException != null) {
            // Handle server-side exceptions. 
            Log.e("ErrorCode", serviceException.getErrorCode());
            Log.e("RequestId", serviceException.getRequestId());
            Log.e("HostId", serviceException.getHostId());
            Log.e("RawMessage", serviceException.getRawMessage());
        }
    }
});

Copy objects

The following code provides an example on how to prevent an existing object from being overwritten when you copy an object with the same name:

// Specify the name of the source bucket. 
String srcBucketName = "srcbucket";
// Specify the full path of the object in the source bucket. 
String srcObjectKey = "dir1/srcobject.txt";
// Specify the name of the destination bucket. 
String destBucketName = "destbucket";
// Specify the full path of the object in the destination bucket. 
String destObjectKey = "dir2/destobject.txt";
// Construct a request to copy the object. 
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketName, srcObjectKey, destBucketName, destObjectKey);

ObjectMetadata metadata = new ObjectMetadata();

// Specify whether to overwrite the object with the same name. 
// By default, if x-oss-forbid-overwrite is not specified, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to false, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to true, existing objects are not overwritten by the objects with the same names. If an existing object has the same name as the copied object, an error is reported. 
metadata.setHeader("x-oss-forbid-overwrite", "true");
copyObjectRequest.setNewObjectMetadata(metadata);

// Copy the object in asynchronous mode. 
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) {
        // Handle request exceptions. 
        if (clientExcepion != null) {
            // Handle client-side exceptions such as network errors. 
            clientExcepion.printStackTrace();
        }
        if (serviceException != null) {
            // Handle service exceptions. 
            Log.e("ErrorCode", serviceException.getErrorCode());
            Log.e("RequestId", serviceException.getRequestId());
            Log.e("HostId", serviceException.getHostId());
            Log.e("RawMessage", serviceException.getRawMessage());
        }
    }
});

Multipart upload

The following code provides an example on how to prevent objects from being overwritten by objects with the same names in multipart upload:

// Specify the name of the bucket. Example: examplebucket. 
String bucketName = "examplebucket";
// Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: exampledir/exampleobject.txt. 
String objectKey = "exampledir/exampleobject.txt";
// Specify the full path of the local file that you want to upload. 
String localFile = "/storage/emulated/0/oss/examplefile.txt";

// Initiate a multipart upload task. 
InitiateMultipartUploadRequest init = new InitiateMultipartUploadRequest(bucketName, objectKey);
ObjectMetadata metadata = new ObjectMetadata();
// Specify whether to overwrite the object with the same name. 
// By default, if x-oss-forbid-overwrite is not specified, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to false, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to true, existing objects are not overwritten by the objects with the same names. If an existing object has the same name as the uploaded object, an error is reported. 
metadata.setHeader("x-oss-forbid-overwrite", "true");
init.setMetadata(metadata);

InitiateMultipartUploadResult initResult = oss.initMultipartUpload(init);
// Obtain the upload ID. The upload ID uniquely identifies the multipart upload task. You can use the upload ID to cancel or query the multipart upload task. 
String uploadId = initResult.getUploadId();

// Specify the size of a single part. Unit: bytes. Valid values: 100 KB to 5 GB. 
int partCount = 100 * 1024;
// Start the multipart upload task. 
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);
    // Specify the part number for each part. The number starts from 1. Each part to upload has a part number. Valid values: 1 to 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;
        }
    }
});

// Complete the multipart upload task. 
CompleteMultipartUploadRequest complete = new CompleteMultipartUploadRequest(bucketName, objectKey, uploadId, partETags);
metadata = new ObjectMetadata();
// Specify whether to overwrite the object with the same name. 
// By default, if x-oss-forbid-overwrite is not specified, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to false, existing objects are overwritten by the objects with the same names. 
// If x-oss-forbid-overwrite is set to true, existing objects are not overwritten by the objects with the same names. If an existing object has the same name as the uploaded object, an error is reported. 
metadata.setHeader("x-oss-forbid-overwrite", "true");
complete.setMetadata(metadata);
CompleteMultipartUploadResult completeResult = oss.completeMultipartUpload(complete);           

References

  • For more information about the API operation that you can call to perform simple upload, see PutObject.
  • For more information about the API operation that you can call to copy an object, see CopyObject.
  • The multipart upload task involves the following three API operations:
    • The API operation that you can call to initiate a multipart upload task. For more information, see InitiateMultipartUpload.
    • The API operation that you can call to upload data by part. For more information, see UploadPart.
    • The API operation that you can call to complete the multipart upload task. For more information, see CompleteMultipartUpload.