By default, if you upload an object that has the same name as an existing object, 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 that have the same names in simple upload:

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.ByteArrayInputStream;

public class Demo {
    public static void main(String[] args) throws Exception {
        // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access Object Storage Service (OSS) is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
        String accessKeyId = "yourAccessKeyId";
        String accessKeySecret = "yourAccessKeySecret";
        // Specify the bucket name. Example: examplebucket. 
        String bucketName = "examplebucket";
        // Specify the full path of the object. The full path of the object cannot contain the bucket name. 
        String objectName = "exampledir/object";
        String content = "Hello OSS!";

        // Create an OSSClient instance. 
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // Create a PutObjectRequest object. 
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));

            // Specify whether to overwrite the existing 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 object with the same name already exists, an error is reported. 
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader("x-oss-forbid-overwrite", "true");
            putObjectRequest.setMetadata(metadata);

            // Upload the object. 
            ossClient.putObject(putObjectRequest);
        } 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();
            }
        }
    }
}

Copy objects

  • Use CopyObjectRequest to copy objects

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

    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.*;
    
    public class Demo {
        public static void main(String[] args) throws Exception {
            // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // Specify the name of the source bucket. 
            String sourceBucketName = "srcexamplebucket";
            // Specify the full path of the source object. The full path of the object cannot contain the bucket name. 
            String sourceObjectName = "srcexampleobject.txt";
            // Specify the name of the destination bucket. The destination bucket must be in the same region as the source bucket. 
            String destinationBucketName = "desexamplebucket";
            // Specify the full path of the destination object. The full path of the object cannot contain the bucket name. 
            String destinationObjectName = "desexampleobject.txt";
    
            // Create an OSSClient instance. 
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
            try {
                // Create a CopyObjectRequest object. 
                CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName);
    
                // Configure the metadata of the destination object. 
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentType("text/html");
                // Specify whether to overwrite the existing 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 object with the same name already exists, an error is reported. 
                metadata.setHeader("x-oss-forbid-overwrite", "true");
                copyObjectRequest.setNewObjectMetadata(metadata);
    
                // Copy the object. 
                CopyObjectResult result = ossClient.copyObject(copyObjectRequest);
                System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
            } 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();
                }
            }
        }
    }
  • Copy a large object

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

    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.util.ArrayList;
    import java.util.List;
    
    public class Demo {
        public static void main(String[] args) throws Exception {
            // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // Specify the name of the source bucket. 
            String sourceBucketName = "srcexamplebucket";
            // Specify the full path of the source object. The full path of the object cannot contain the bucket name. 
            String sourceObjectName = "srcexampleobject.txt";
            // Specify the name of the destination bucket. The destination bucket must be in the same region as the source bucket. 
            String destinationBucketName = "desexamplebucket";
            // Specify the full path of the destination object. The full path of the object cannot contain the bucket name. 
            String destinationObjectName = "desexampleobject.txt";
    
            // Create an OSSClient instance. 
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
            try {
                ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceObjectName);
                // Obtain the size of the object to copy. 
                long contentLength = objectMetadata.getContentLength();
    
                // Set the size of each part to 10 MB. 
                long partSize = 1024 * 1024 * 10;
    
                // Calculate the total number of parts. 
                int partCount = (int) (contentLength / partSize);
                if (contentLength % partSize != 0) {
                    partCount++;
                }
                System.out.println("total part count:" + partCount);
    
                // Initiate a multipart copy task. You can use InitiateMultipartUploadRequest to specify the metadata of the destination object. 
                InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(destinationBucketName, destinationObjectName);
                // Specify whether to overwrite the existing 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 object with the same name already exists, an error is reported. 
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setHeader("x-oss-forbid-overwrite", "true");
                initiateMultipartUploadRequest.setObjectMetadata(metadata);
    
                InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest);
                String uploadId = initiateMultipartUploadResult.getUploadId();
    
                // Start the multipart copy task. 
                List<PartETag> partETags = new ArrayList<PartETag>();
                for (int i = 0; i < partCount; i++) {
                    // Calculate the size of each part. 
                    long skipBytes = partSize * i;
                    long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes;
    
                    // Create an UploadPartCopyRequest object. You can use UploadPartCopyRequest to specify conditions. 
                    UploadPartCopyRequest uploadPartCopyRequest =
                            new UploadPartCopyRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName);
                    uploadPartCopyRequest.setUploadId(uploadId);
                    uploadPartCopyRequest.setPartSize(size);
                    uploadPartCopyRequest.setBeginIndex(skipBytes);
                    uploadPartCopyRequest.setPartNumber(i + 1);
                    UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest);
    
                    // Store the returned part ETags in partETags. 
                    partETags.add(uploadPartCopyResult.getPartETag());
                }
    
                // Complete the multipart copy task. 
                CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(
                        destinationBucketName, destinationObjectName, uploadId, partETags);
    
                // Specify whether to overwrite the existing 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 object with the same name already exists, an error is reported. 
                completeMultipartUploadRequest.addHeader("x-oss-forbid-overwrite", "true");
    
                ossClient.completeMultipartUpload(completeMultipartUploadRequest);
            } 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();
                }
            }
        }
    }

Multipart upload

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

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 {
        // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
        String accessKeyId = "yourAccessKeyId";
        String accessKeySecret = "yourAccessKeySecret";
        // Specify the bucket name. Example: examplebucket. 
        String bucketName = "examplebucket";
        // Specify the full path of the object. The full path of the object cannot contain the bucket name. 
        String objectName = "exampledir/object";

        // Create an OSSClient instance. 
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // Create an InitiateMultipartUploadRequest object. 
            InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);

            // Specify whether to overwrite the existing 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 object with the same name already exists, an error is reported. 
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader("x-oss-forbid-overwrite", "true");
            request.setObjectMetadata(metadata);

            // Initiate a multipart upload task. 
            InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
            // Obtain the upload ID. The upload ID is the unique identification of a multipart upload task. You can initiate related requests based on the upload ID, such as canceling a multipart upload task and querying a multipart upload task. 
            String uploadId = upresult.getUploadId();

            // partETags is the set of PartETags. A PartETag consists of the part number and ETag of an uploaded part. 
            List<PartETag> partETags =  new ArrayList<PartETag>();
            // Calculate the total number of parts to upload. 
            final long partSize = 1 * 1024 * 1024L;   // 1MB
            final File sampleFile = new File("<localFile>");
            long fileLength = sampleFile.length();
            int partCount = (int) (fileLength / partSize);
            if (fileLength % partSize != 0) {
                partCount++;
            }
            // Upload each part until all parts are uploaded. 
            for (int i = 0; i < partCount; i++) {
                long startPos = i * partSize;
                long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
                InputStream instream = new FileInputStream(sampleFile);
                // Skip the parts that have been uploaded. 
                instream.skip(startPos);
                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(objectName);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setInputStream(instream);
                // Configure the size of each part. All parts except for the last part must be at least 5 MB in size. 
                uploadPartRequest.setPartSize(curPartSize);
                // Configure part numbers. Each part is configured with a part number. The value can be from 1 to 10,000. If you configure a number beyond the range, OSS returns an InvalidArgument error code. 
                uploadPartRequest.setPartNumber( i + 1);
                // Parts are not necessarily uploaded in sequence. They can be uploaded from different OSS clients. OSS sorts the parts based on their part numbers and combines them into a complete object. 
                UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
                // After you upload a part, OSS returns a result that contains a PartETag. The PartETag is stored in partETags. 
                partETags.add(uploadPartResult.getPartETag());
            }


            // Create a CompleteMultipartUploadRequest object. 
            // When the multipart upload task is completed, you must provide all valid PartETags. After OSS receives the PartETags, OSS verifies all parts one by one. After all parts are verified, OSS combines these parts into a complete object. 
            CompleteMultipartUploadRequest completeMultipartUploadRequest =
                    new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);

            // Specify whether to overwrite the existing 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 object with the same name already exists, an error is reported. 
            completeMultipartUploadRequest.addHeader("x-oss-forbid-overwrite", "true");

            // Complete the multipart upload task. 
            CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
        } 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();
            }
        }
    }
}

References

  • For the complete sample code that is used to prevent existing objects from being overwritten by objects that have the same names in object upload scenarios, visit GitHub.
  • 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 the API operations that you can call to perform multipart upload, see InitiateMultipartUpload and CompleteMultipartUpload.