All Products
Search
Document Center

Object Storage Service:Salin objek (Java SDK V1)

Last Updated:Aug 26, 2026

Salin objek dalam satu bucket atau antar-bucket di wilayah yang sama.

Catatan

  • Topik ini menggunakan titik akhir publik wilayah China (Hangzhou). Untuk mengakses OSS dari layanan Alibaba Cloud lainnya di wilayah yang sama, gunakan titik akhir internal. Untuk detail wilayah dan titik akhir yang didukung, lihat Regions and endpoints.

  • Pada topik ini, kredensial akses diperoleh dari variabel lingkungan. Untuk informasi selengkapnya, lihat 配置访问凭证.

  • Topik ini menunjukkan cara membuat instans OSSClient dengan titik akhir OSS. Untuk konfigurasi alternatif, seperti menggunakan domain kustom atau autentikasi dengan kredensial dari Security Token Service (STS), lihat Client configuration.

  • Anda harus memiliki izin baca pada objek sumber dan izin baca/tulis pada bucket tujuan.

  • Bucket sumber dan tujuan tidak boleh memiliki kebijakan retensi yang dikonfigurasi. Jika tidak, operasi salin akan gagal dan mengembalikan error The object you specified is immutable..

  • Salin lintas-wilayah tidak didukung. Misalnya, Anda tidak dapat menyalin objek dari bucket China (Hangzhou) ke bucket China (Qingdao).

Salin objek kecil

Gunakan ossClient.copyObject untuk menyalin objek berukuran kurang dari 1 GB. Metode ini menerima parameter melalui dua cara:

Menentukan parameter

Deskripsi

CopyObjectResult copyObject(String sourceBucketName, String sourceKey, String destinationBucketName, String destinationKey)

Menentukan bucket dan objek sumber serta tujuan. Menyalin konten dan metadata dari objek sumber (salin simple).

CopyObjectResult copyObject(CopyObjectRequest copyObjectRequest)

Menentukan metadata dan kondisi salin untuk objek tujuan. Jika sumber dan tujuan adalah objek yang sama, metadata sumber akan diganti.

Parameter CopyObjectRequest:

Parameter

Deskripsi

Metode

sourceBucketName

Nama bucket sumber.

setSourceBucketName(String sourceBucketName)

sourceKey

Nama objek sumber.

setSourceKey(String sourceKey)

destinationBucketName

Nama bucket tujuan.

setDestinationBucketName(String destinationBucketName)

destinationKey

Nama objek tujuan.

setDestinationKey(String destinationKey)

newObjectMetadata

Metadata objek tujuan.

setNewObjectMetadata(ObjectMetadata newObjectMetadata)

matchingETagConstraints

Kondisi salin. Menyalin objek hanya jika ETag sumber sesuai dengan nilai yang ditentukan. Jika tidak, mengembalikan error.

setMatchingETagConstraints(List<String> matchingETagConstraints)

nonmatchingEtagConstraints

Kondisi salin. Menyalin objek hanya jika ETag sumber tidak sesuai dengan nilai yang ditentukan. Jika tidak, mengembalikan error.

setNonmatchingETagConstraints(List<String> nonmatchingEtagConstraints)

unmodifiedSinceConstraint

Kondisi salin. Menyalin objek hanya jika sumber belum dimodifikasi sejak waktu yang ditentukan. Jika tidak, mengembalikan error.

setUnmodifiedSinceConstraint(Date unmodifiedSinceConstraint)

modifiedSinceConstraint

Kondisi salin. Menyalin objek hanya jika sumber telah dimodifikasi setelah waktu yang ditentukan. Jika tidak, mengembalikan error.

setModifiedSinceConstraint(Date modifiedSinceConstraint)

Parameter CopyObjectResult:

Parameter

Deskripsi

Metode

etag

Identifier unik objek.

String getETag()

lastModified

Waktu modifikasi terakhir objek.

Date getLastModified()

Salin objek kecil menggunakan salah satu metode berikut:

  • Salin simple

    Contoh berikut menyalin srcexampleobject.txt dari srcexamplebucket ke desexampleobject.txt di desexamplebucket.

    import com.aliyun.oss.*;
    import com.aliyun.oss.common.auth.*;
    import com.aliyun.oss.common.comm.SignVersion;
    import com.aliyun.oss.model.*;
    
    public class Demo {
        public static void main(String[] args) throws Exception {
            // Wilayah China (Hangzhou) digunakan sebagai contoh. Tentukan titik akhir yang sebenarnya.
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
            EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            // Tentukan nama bucket sumber.
            String sourceBucketName = "srcexamplebucket";
            // Tentukan path lengkap objek sumber. Path lengkap tidak boleh mengandung nama bucket.
            String sourceKey = "srcexampleobject.txt";
            // Tentukan nama bucket tujuan. Bucket tujuan harus berada di wilayah yang sama dengan bucket sumber.
            String destinationBucketName = "desexamplebucket";
            // Tentukan path lengkap objek tujuan. Path lengkap tidak boleh mengandung nama bucket.
            String destinationKey = "desexampleobject.txt";
            // Tentukan wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah China (Hangzhou), atur wilayah menjadi cn-hangzhou.
            String region = "cn-hangzhou";
    
            // Buat instans OSSClient.
            // Setelah instans OSSClient tidak digunakan lagi, panggil metode shutdown untuk melepas sumber daya.
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
            OSS ossClient = OSSClientBuilder.create()
            .endpoint(endpoint)
            .credentialsProvider(credentialsProvider)
            .clientConfiguration(clientBuilderConfiguration)
            .region(region)               
            .build();
    
            try {
                // Salin file.
                CopyObjectResult result = ossClient.copyObject(sourceBucketName, sourceKey, destinationBucketName, destinationKey);
                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();
                }
            }
        }
    }                   
  • Salin menggunakan CopyObjectRequest

    Contoh berikut menggunakan CopyObjectRequest untuk menyalin srcexampleobject.txt dari srcexamplebucket ke desexampleobject.txt di desexamplebucket.

    import com.aliyun.oss.*;
    import com.aliyun.oss.common.auth.*;
    import com.aliyun.oss.common.comm.SignVersion;
    import com.aliyun.oss.model.*;
    
    public class Demo {
        public static void main(String[] args) throws Exception {
            // Wilayah China (Hangzhou) digunakan sebagai contoh. Tentukan titik akhir yang sebenarnya.
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode contoh, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah dikonfigurasi.
            EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            // Tentukan nama bucket sumber.
            String sourceBucketName = "srcexamplebucket";
            // Tentukan path lengkap objek sumber. Path lengkap tidak boleh mengandung nama bucket.
            String sourceKey = "srcexampleobject.txt";
            // Tentukan nama bucket tujuan. Bucket tujuan harus berada di wilayah yang sama dengan bucket sumber.
            String destinationBucketName = "desexamplebucket";
            // Tentukan path lengkap objek tujuan. Path lengkap tidak boleh mengandung nama bucket.
            String destinationKey = "desexampleobject.txt";
            // Tentukan wilayah tempat bucket berada. Misalnya, jika bucket berada di wilayah China (Hangzhou), atur wilayah menjadi cn-hangzhou.
            String region = "cn-hangzhou";
    
            // Buat instans OSSClient.
            // Setelah instans OSSClient tidak digunakan lagi, panggil metode shutdown untuk melepas sumber daya.
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
            OSS ossClient = OSSClientBuilder.create()
            .endpoint(endpoint)
            .credentialsProvider(credentialsProvider)
            .clientConfiguration(clientBuilderConfiguration)
            .region(region)               
            .build();
    
            try {
                // Buat objek CopyObjectRequest.
                CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceKey, destinationBucketName, destinationKey);
    
                // Atur metadata file baru.
                ObjectMetadata meta = new ObjectMetadata();
                meta.setContentType("text/plain");
                // Tentukan apakah objek tujuan akan ditimpa jika namanya sama. Pada contoh ini, parameter ini diatur ke true, yang berarti objek tujuan tidak dapat ditimpa.
                // meta.setHeader("x-oss-forbid-overwrite", "true");
                // Tentukan alamat sumber untuk operasi salin.
                // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE, "/examplebucket/recode-test.txt");
                // Jika ETag objek sumber sesuai dengan ETag yang ditentukan, operasi salin dilakukan dan respons 200 OK dikembalikan.
                // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
                // Jika ETag objek sumber tidak sesuai dengan ETag yang ditentukan, operasi salin dilakukan dan respons 200 OK dikembalikan.
                // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_NONE_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
                // Jika waktu yang ditentukan sama dengan atau lebih baru daripada waktu modifikasi aktual objek, objek disalin dan respons 200 OK dikembalikan.
                // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_UNMODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
                // Jika objek sumber telah dimodifikasi setelah waktu yang ditentukan, operasi salin dilakukan.
                // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
                // Tentukan cara mengatur metadata objek tujuan. Pada contoh ini, parameter ini diatur ke COPY, yang berarti metadata objek sumber disalin ke objek tujuan.
                // meta.setHeader(OSSHeaders.COPY_OBJECT_METADATA_DIRECTIVE, "COPY");
                // Tentukan algoritma enkripsi sisi server yang digunakan OSS untuk membuat objek tujuan.
                // meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION);
                // Kunci master pelanggan (CMK) yang dikelola oleh KMS. Parameter ini hanya berlaku ketika x-oss-server-side-encryption diatur ke KMS.
                // meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION_KEY_ID, "9468da86-3509-4f8d-a61e-6eab1eac****");
                // Tentukan izin akses untuk objek tujuan saat dibuat di OSS. Pada contoh ini, parameter ini diatur ke Private, yang berarti hanya pemilik objek dan pengguna yang berwenang yang memiliki izin baca/tulis. Pengguna lain tidak dapat mengakses objek tersebut.
                // meta.setHeader(OSSHeaders.OSS_OBJECT_ACL, CannedAccessControlList.Private);
                // Tentukan kelas penyimpanan objek. Pada contoh ini, parameter ini diatur ke Standard.
                // meta.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard);
                // Tentukan tag untuk objek. Anda dapat menentukan beberapa tag.
                // meta.setHeader(OSSHeaders.OSS_TAGGING, "a:1");
                // Tentukan cara mengatur tag untuk objek tujuan. Pada contoh ini, parameter ini diatur ke COPY, yang berarti tag objek sumber disalin ke objek tujuan.
                // meta.setHeader(OSSHeaders.COPY_OBJECT_TAGGING_DIRECTIVE, "COPY");
                copyObjectRequest.setNewObjectMetadata(meta);
    
                // Salin file.
                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();
                }
            }
        }
    }                 

Salin objek besar

Untuk objek berukuran lebih dari 1 GB, gunakan salin multipart (UploadPartCopy). Proses ini terdiri dari tiga langkah:

  1. Inisialisasi tugas salin multipart dengan ossClient.initiateMultipartUpload.

  2. Salin setiap bagian dengan ossClient.uploadPartCopy. Semua bagian, kecuali bagian terakhir, harus berukuran lebih dari 100 KB.

  3. Selesaikan tugas salin multipart dengan ossClient.completeMultipartUpload.

Contoh berikut menggunakan salin multipart untuk menyalin srcexampleobject.txt dari srcexamplebucket ke desexampleobject.txt di desexamplebucket.

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import java.util.ArrayList;
import java.util.List;

public class Demo {
    public static void main(String[] args) throws Exception {
        // Titik akhir wilayah China (Hangzhou) digunakan sebagai contoh. Untuk wilayah lain, tentukan titik akhir yang sebenarnya.
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Peroleh kredensial akses dari variabel lingkungan. Sebelum menjalankan kode ini, pastikan variabel lingkungan OSS_ACCESS_KEY_ID dan OSS_ACCESS_KEY_SECRET telah diatur.
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Tentukan nama bucket sumber.
        String sourceBucketName = "srcexamplebucket";
        // Tentukan path lengkap objek sumber. Path lengkap tidak boleh mencakup nama bucket.
        String sourceKey = "srcexampleobject.txt";
        // Tentukan nama bucket tujuan. Bucket tujuan harus berada di wilayah yang sama dengan bucket sumber.
        String destinationBucketName = "desexamplebucket";
        // Tentukan path lengkap objek tujuan. Path lengkap tidak boleh mencakup nama bucket.
        String destinationKey = "desexampleobject.txt";
        // Tentukan wilayah tempat bucket berada. Contoh ini menggunakan wilayah China (Hangzhou). Atur Region ke cn-hangzhou.
        String region = "cn-hangzhou";

        // Buat instans OSSClient.
        // Setelah instans OSSClient tidak diperlukan lagi, panggil metode shutdown untuk melepas sumber daya.
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceKey);
            // Dapatkan ukuran file yang akan disalin.
            long contentLength = objectMetadata.getContentLength();

            // Atur ukuran bagian menjadi 10 MB. Satuannya byte.
            long partSize = 1024 * 1024 * 10;

            // Hitung jumlah total bagian.
            int partCount = (int) (contentLength / partSize);
            if (contentLength % partSize != 0) {
                partCount++;
            }
            System.out.println("total part count:" + partCount);

            // Inisialisasi tugas salin. Anda dapat menggunakan InitiateMultipartUploadRequest untuk menentukan metadata objek tujuan.
            InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(destinationBucketName, destinationKey);
            // Salin ContentType dan UserMetadata dari file sumber. Secara default, salin multipart tidak menyalinnya.
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(objectMetadata.getContentType());
            metadata.setUserMetadata(objectMetadata.getUserMetadata());
            initiateMultipartUploadRequest.setObjectMetadata(metadata);
            InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest);
            String uploadId = initiateMultipartUploadResult.getUploadId();

            // Salin bagian-bagian.
            List<PartETag> partETags = new ArrayList<PartETag>();
            for (int i = 0; i < partCount; i++) {
                // Hitung ukuran setiap bagian.
                long skipBytes = partSize * i;
                long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes;

                // Buat UploadPartCopyRequest. Anda dapat menggunakan UploadPartCopyRequest untuk menentukan kondisi.
                UploadPartCopyRequest uploadPartCopyRequest =
                        new UploadPartCopyRequest(sourceBucketName, sourceKey, destinationBucketName, destinationKey);
                uploadPartCopyRequest.setUploadId(uploadId);
                uploadPartCopyRequest.setPartSize(size);
                uploadPartCopyRequest.setBeginIndex(skipBytes);
                uploadPartCopyRequest.setPartNumber(i + 1);
                //Map headers = new HashMap();
                // Tentukan alamat sumber untuk operasi salin.
                // headers.put(OSSHeaders.COPY_OBJECT_SOURCE, "/examplebucket/desexampleobject.txt");
                // Tentukan rentang salin objek sumber. Misalnya, atur bytes=0-1023 untuk menyalin 1024 byte pertama.
                // headers.put(OSSHeaders.COPY_SOURCE_RANGE, "bytes=0-1023");
                // Jika ETag objek sumber sesuai dengan ETag yang Anda berikan, operasi salin dilakukan dan respons 200 OK dikembalikan.
                // headers.put(OSSHeaders.COPY_OBJECT_SOURCE_IF_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
                // Jika ETag objek sumber tidak sesuai dengan ETag yang Anda berikan, operasi salin dilakukan dan respons 200 OK dikembalikan.
                // headers.put(OSSHeaders.COPY_OBJECT_SOURCE_IF_NONE_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
                // Jika waktu yang ditentukan sama dengan atau lebih baru daripada waktu modifikasi aktual file, file disalin dan respons 200 OK dikembalikan.
                // headers.put(OSSHeaders.COPY_OBJECT_SOURCE_IF_UNMODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
                // Jika objek sumber telah dimodifikasi setelah waktu yang Anda tentukan, operasi salin dilakukan.
                // headers.put(OSSHeaders.COPY_OBJECT_SOURCE_IF_MODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
                // uploadPartCopyRequest.setHeaders(headers);
                UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest);

                // Simpan ETag bagian yang dikembalikan ke partETags.
                partETags.add(uploadPartCopyResult.getPartETag());
            }

            // Selesaikan tugas salin multipart.
            CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(
                    destinationBucketName, destinationKey, uploadId, partETags);
            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();
            }
        }
    }
}

Referensi