All Products
Search
Document Center

Object Storage Service:Prevent objects from being overwritten by objects with the same names

Last Updated:Mar 07, 2024

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.

Usage notes

  • Before you run the sample code in this topic, you must create an OSSClient instance by using methods such as using a custom domain name or Security Token Service (STS). For more information, see Initialization.

Prevent overwrites in a simple upload task

The following sample code provides an example on how to prevent existing objects from being overwritten by objects that have the same names when you perform simple upload:

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

// Specify whether to overwrite an existing object with the same name. 
// By default, if x-oss-forbid-overwrite is not specified, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to false, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to true, an existing object with the same name is not overwritten. If an object with the same name already exists, 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());
        }
    }
});

Prevent overwrites in an object copy task

The following sample code provides an example on how to prevent an existing object in a bucket from being overwritten by an object that has the same name in an object copy task:

// Specify the name of the source bucket. 
String srcBucketName = "srcbucket";
// Specify the full path of the source object. 
String srcObjectKey = "dir1/srcobject.txt";
// Specify the name of the destination bucket. 
String destBucketName = "destbucket";
// Specify the full path of the destination object. 
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, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to false, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to true, an existing object with the same name is not overwritten. If an object with the same name already exists, 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());
        }
    }
});

Prevent overwrites in a multipart upload task

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

// Specify the name of the bucket. Example: examplebucket. 
String bucketName = "examplebucket";
// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
String objectKey = "exampledir/exampleobject.txt";
// Specify the full path of the local file 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 an existing object with the same name. 
// By default, if x-oss-forbid-overwrite is not specified, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to false, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to true, an existing object with the same name is not overwritten. If an object with the same name already exists, 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 perform related operations, such as canceling and querying 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 of each part. The numbers start from 1. Each part 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, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to false, an existing object with the same name is overwritten. 
// If x-oss-forbid-overwrite is set to true, an existing object with the same name is not overwritten. If an object with the same name already exists, 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.

  • For more information about how to initialize an OSSClient instance, see Initialization.

  • A multipart upload involves three API operations. For more information about the operations, see the following topics: