Layanan Penyimpanan Objek (OSS) menyediakan fitur unggah multi-bagian yang memungkinkan Anda membagi objek besar menjadi beberapa bagian dan mengunggahnya secara independen. Setelah semua bagian diunggah, Anda dapat memanggil operasi CompleteMultipartUpload untuk menggabungkan bagian-bagian tersebut menjadi satu objek utuh. Proses ini mendukung unggah yang dapat dilanjutkan.
Catatan
Pada topik ini, digunakan titik akhir publik wilayah China (Hangzhou). Untuk mengakses OSS dari layanan Alibaba Cloud lainnya dalam wilayah yang sama, gunakan titik akhir internal. Untuk detail wilayah dan titik akhir yang didukung, lihat Wilayah dan titik akhir.
Pada topik ini, kredensial akses diperoleh dari variabel lingkungan. Untuk informasi lebih lanjut tentang cara mengonfigurasi kredensial akses, lihat Konfigurasi kredensial akses.
Pada topik ini, instans OSSClient dibuat menggunakan titik akhir OSS. Jika Anda ingin membuat instans OSSClient menggunakan nama domain kustom atau Security Token Service (STS), lihat Contoh konfigurasi untuk skenario umum.
Untuk menyelesaikan proses unggah multi-bagian—yang mencakup operasi InitiateMultipartUpload, UploadPart, dan CompleteMultipartUpload—Anda harus memiliki izin
oss:PutObject. Untuk informasi lebih lanjut, lihat Berikan kebijakan akses kustom kepada RAM user.
Proses unggah multi-bagian
Unggah multi-bagian terdiri dari tiga langkah berikut:
Inisialisasi event unggah multi-bagian.
Panggil metode ossClient.initiateMultipartUpload. OSS mengembalikan upload ID yang unik secara global dalam respons.
Unggah bagian-bagian.
Panggil metode ossClient.uploadPart untuk mengunggah data bagian.
CatatanUntuk upload ID yang sama, nomor bagian menentukan posisi bagian tersebut dalam keseluruhan file. Jika Anda mengunggah data baru dengan nomor bagian yang sama, data bagian yang ada di OSS akan ditimpa.
OSS mengembalikan hash MD5 dari data bagian yang diterima dalam header ETag pada respons.
OSS menghitung hash MD5 dari data yang diunggah dan membandingkannya dengan hash MD5 yang dihitung oleh SDK. Jika kedua hash MD5 tidak cocok, kode kesalahan InvalidDigest dikembalikan.
Selesaikan unggah multi-bagian.
Setelah semua bagian diunggah, panggil metode ossClient.completeMultipartUpload untuk menggabungkan bagian-bagian tersebut menjadi satu file utuh.
Kode contoh
Contoh berikut menunjukkan proses lengkap unggah multi-bagian:
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.Mimetypes;
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 {
// Titik akhir wilayah China (Hangzhou) digunakan sebagai contoh. Tentukan Titik akhir yang sebenarnya.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Dapatkan 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, misalnya examplebucket.
String bucketName = "examplebucket";
// Tentukan path lengkap objek, misalnya exampledir/exampleobject.txt. Path lengkap tidak boleh mengandung nama bucket.
String objectName = "exampledir/exampleobject.txt";
// Path file lokal yang akan diunggah.
String filePath = "D:\\localpath\\examplefile.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.
// Saat instans OSSClient tidak lagi digunakan, panggil metode shutdown untuk melepaskan 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 InitiateMultipartUploadRequest.
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
// Buat objek ObjectMetadata dan atur Content-Type.
ObjectMetadata metadata = new ObjectMetadata();
if (metadata.getContentType() == null) {
metadata.setContentType(Mimetypes.getInstance().getMimetype(new File(filePath), objectName));
}
System.out.println("Content-Type: " + metadata.getContentType());
// Kaitkan metadata ke permintaan unggah.
request.setObjectMetadata(metadata);
// Inisialisasi unggah multi-bagian.
InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
// Kembalikan upload ID.
String uploadId = upresult.getUploadId();
// partETags adalah kumpulan objek PartETag. Objek PartETag terdiri dari ETag dan nomor bagian suatu bagian.
List<PartETag> partETags = new ArrayList<PartETag>();
// Ukuran setiap bagian. Ini digunakan untuk menghitung jumlah bagian. Satuan: byte.
// Ukuran bagian minimum adalah 100 KB, dan ukuran bagian maksimum adalah 5 GB. Ukuran bagian terakhir dapat lebih kecil dari 100 KB.
// Atur ukuran bagian menjadi 1 MB.
final long partSize = 1 * 1024 * 1024L;
// Hitung jumlah bagian berdasarkan ukuran data yang akan diunggah. Kode berikut memberikan contoh cara mendapatkan ukuran data yang akan diunggah dari file lokal menggunakan File.length().
final File sampleFile = new File(filePath);
long fileLength = sampleFile.length();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// Iterasi melalui bagian-bagian dan unggah semuanya.
for (int i = 0; i < partCount; i++) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
// Atur aliran bagian yang akan diunggah.
// Kode berikut memberikan contoh cara membuat objek FileInputStream dari file lokal dan melewati data tertentu menggunakan metode InputStream.skip().
InputStream instream = new FileInputStream(sampleFile);
instream.skip(startPos);
uploadPartRequest.setInputStream(instream);
// Atur ukuran bagian.
uploadPartRequest.setPartSize(curPartSize);
// Atur nomor bagian. Setiap bagian yang diunggah memiliki nomor bagian yang berkisar antara 1 hingga 10.000. Jika nomor bagian berada di luar rentang tersebut, OSS mengembalikan kode kesalahan InvalidArgument.
uploadPartRequest.setPartNumber(i + 1);
// Bagian tidak perlu diunggah secara berurutan. Bahkan, bagian dapat diunggah dari client yang berbeda. OSS mengurutkan bagian berdasarkan nomor bagian untuk membuat file utuh.
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
// Setelah setiap bagian diunggah, respons OSS mencakup PartETag. PartETag disimpan dalam partETags.
partETags.add(uploadPartResult.getPartETag());
// Tutup aliran.
instream.close();
}
// Buat objek CompleteMultipartUploadRequest.
// Saat menyelesaikan unggah multi-bagian, Anda harus menyediakan semua partETags yang valid. Setelah OSS menerima partETags yang dikirimkan, OSS memverifikasi validitas setiap bagian. Setelah semua bagian diverifikasi, OSS menggabungkan bagian-bagian tersebut menjadi satu file utuh.
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
// Selesaikan unggah multi-bagian.
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
System.out.println("Unggah berhasil, ETag: " + completeMultipartUploadResult.getETag());
} catch (OSSException oe) {
System.out.println("Terjadi OSSException, yang berarti permintaan Anda sampai ke OSS, "
+ "tetapi ditolak dengan respons kesalahan karena suatu alasan.");
System.out.println("Pesan Kesalahan:" + oe.getErrorMessage());
System.out.println("Kode Kesalahan:" + oe.getErrorCode());
System.out.println("ID Permintaan:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Terjadi ClientException, yang berarti client mengalami "
+ "masalah internal serius saat mencoba berkomunikasi dengan OSS, "
+ "seperti tidak dapat mengakses jaringan.");
System.out.println("Pesan Kesalahan:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}Skenario Umum
Atur metadata saat menginisialisasi unggah multi-bagian
Atur izin akses file saat menyelesaikan unggah multi-bagian
Otomatis proses part ETags saat menyelesaikan unggah multi-bagian
Batalkan event unggah multi-bagian
Cantumkan bagian yang telah diunggah
Cantumkan event unggah multi-bagian
Lakukan unggah multi-bagian untuk aliran jaringan atau aliran data
Referensi
Untuk kode contoh lengkap unggah multi-bagian, lihat Contoh GitHub.
Unggah multi-bagian melibatkan tiga operasi API. Untuk informasi lebih lanjut tentang operasi tersebut, lihat topik berikut:
Untuk informasi lebih lanjut tentang operasi API yang digunakan untuk membatalkan event unggah multi-bagian, lihat AbortMultipartUpload.
Untuk informasi lebih lanjut tentang operasi API yang digunakan untuk mencantumkan bagian yang telah diunggah, lihat ListParts.
Untuk informasi lebih lanjut tentang operasi API yang digunakan untuk mencantumkan semua event unggah multi-bagian yang sedang berlangsung, lihat ListMultipartUploads.