本文介紹如何將源Bucket中的檔案(Object)複製到同一地區下相同或不同目標Bucket中。
注意事項
本文以華東1(杭州)外網Endpoint為例。如果您希望通過與OSS同地區的其他阿里雲產品訪問OSS,請使用內網Endpoint。關於OSS支援的Region與Endpoint的對應關係,請參見OSS地區和訪問網域名稱。
本文以從環境變數讀取存取憑證為例。如何配置訪問憑證,請參見Java配置訪問憑證。
本文以OSS網域名稱建立OSSClient為例。如果您希望通過自訂網域名、STS等方式建立OSSClient,請參見建立OSSClient。
拷貝檔案時,您必須擁有源檔案的讀許可權及目標Bucket的讀寫權限。
拷貝檔案時,您需要確保源Bucket和目標Bucket均未設定合規保留原則,否則報錯The object you specified is immutable.。
不支援跨地區拷貝。例如不能將華東1(杭州)地區儲存空間中的檔案拷貝到華北1(青島)地區。
拷貝小檔案
您可以通過copy方法在同一個Bucket或者同一個Region下的不同Bucket之間拷貝檔案,檔案大小不能超過1 GB。
同一個Bucket中拷貝檔案
以下代碼用於在同一個Bucket中拷貝檔案。
const OSS = require('ali-oss'); const client = new OSS({ // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。 region: 'yourRegion', // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 accessKeyId: process.env.OSS_ACCESS_KEY_ID, accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET, authorizationV4: true, // 填寫Bucket名稱。例如examplebucket。 bucket: 'examplebucket', // 設定是否啟用HTTPS。設定secure為true時,表示啟用。 // secure: true }) // 拷貝同一個Bucket中的檔案。 async function copySmallObjecInSameBucket() { try { // 填寫拷貝後和拷貝前的檔案完整路徑。檔案完整路徑中不能包含Bucket名稱。 // 設定目標檔案的HTTP頭和自訂目標檔案的中繼資料。 const result = await client.copy('destexampleobject.txt', 'srcexampleobject.txt', { // 指定headers參數,設定目標檔案的HTTP頭。如果未指定headers參數,則目標檔案與源檔案的HTTP頭相同,即拷貝源檔案的HTTP頭。 headers: { 'Cache-Control': 'no-cache', // 如果源Object的ETag值和您提供的ETag相等,則執行拷貝操作,並返回200 OK。 'if-match': '5B3C1A2E053D763E1B002CC607C5****', // 如果源Object的ETag值和您提供的ETag不相等,則執行拷貝操作,並返回200 OK。 'if-none-match': '5B3C1A2E053D763E1B002CC607C5****', // 如果指定的時間早於檔案實際修改時間,則執行拷貝操作,並返回200 OK。 'if-modified-since': '2021-12-09T07:01:56.000Z', // 如果指定的時間晚於檔案實際修改時間,則執行拷貝操作,並返回200 OK。 'if-unmodified-since': '2021-12-09T07:01:56.000Z', // 指定OSS建立目標Object時的存取權限,此處設定為private,表示只有Object的擁有者和授權使用者有該Object的讀寫權限,其他使用者沒有許可權操作該Object。 'x-oss-object-acl': 'private', // 指定Object的對象標籤,可同時設定多個標籤。 'x-oss-tagging': 'Tag1=1&Tag2=2', // 指定CopyObject操作時是否覆蓋同名目標Object。此處設定為true,表示禁止覆蓋同名Object。 'x-oss-forbid-overwrite': 'true', }, // 指定meta參數,自訂目標檔案的中繼資料。如果未指定meta參數,目標檔案與源檔案的中繼資料相同,即拷貝源檔案的中繼資料。 meta: { location: 'hangzhou', year: 2015, people: 'mary', }, }); console.log(result); } catch (e) { console.log(e); } } copySmallObjecInSameBucket()
同一Region下不同Bucket之間拷貝檔案
以下代碼用於在同一個Region下不同Bucket之間拷貝檔案。
const OSS = require('ali-oss'); const client = new OSS({ // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。 region: 'yourRegion', // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 accessKeyId: process.env.OSS_ACCESS_KEY_ID, accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET, authorizationV4: true, // 填寫目標Bucket名稱。 bucket: 'destexamplebucket', }); async function copySmallObjectBetweenBuckets() { try { // 分別填寫拷貝後的檔案名稱destobject.txt、拷貝前的檔案名稱srcobject.txt以及拷貝前檔案所屬的Bucket名稱。 const result = await client.copy('destobject.txt', 'srcobject.txt', 'srcbucket', { // 指定headers參數,設定目標檔案的HTTP頭。如果未指定headers參數,則目標檔案與源檔案的HTTP頭相同,即拷貝源檔案的HTTP頭。 headers: { 'Cache-Control': 'no-cache', }, // 指定meta參數,自訂目標檔案的中繼資料。如果未指定meta參數,目標檔案與源檔案的中繼資料相同,即拷貝源檔案的中繼資料。 meta: { location: 'hangzhou', year: 2015, people: 'mary', }, }); console.log(result); } catch (e) { console.log(e); } } copySmallObjectBetweenBuckets()
拷貝大檔案
對於大於1 GB檔案,您可以使用multipartUploadCopy
方法進行分區拷貝。
以下代碼用於在同一個Region下不同Bucket之間拷貝檔案。
const OSS = require("ali-oss");
const client = new OSS({
// yourregion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
region: 'yourregion',
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
authorizationV4: true,
// 填寫目標Bucket名稱。
bucket: "destexamplebucket",
});
async function copyLargeObjectBetweenDifferentBuckets() {
try {
const copyheaders = {
// 如果源Object的ETag值和使用者提供的ETag相等,則執行拷貝操作;否則返回412 HTTP錯誤碼(預先處理失敗)。
"x-oss-copy-source-if-match": "5B3C1A2E053D763E1B002CC607C5****",
// 如果傳入的ETag值和Object的ETag不匹配,則執行拷貝操作,並返回200 OK;否則返回304 Not Modified。
"x-oss-copy-source-if-none-match": "5B3C1A2E053D763E1B002CC607C5****",
// 如果參數傳入的時間等於或者晚於檔案實際修改時間,則執行拷貝操作,並返回200 OK;否則返回412 precondition failed錯誤。
"x-oss-copy-source-if-unmodified-since": "2022-12-09T07:01:56.000Z",
// 如果指定的時間早於實際修改時間,則執行拷貝操作,並返回200 OK;否則返回304 not modified。
"x-oss-copy-source-if-modified-since": "2022-12-09T07:01:56.000Z",
};
const headers = {
// 指定該Object被下載時的網頁的緩衝行為。
"Cache-Control": "no-cache",
// 指定該Object被下載時的名稱。
"Content-Disposition": "somename",
// 指定該Object被下載時的內容編碼格式。
"Content-Encoding": "utf-8",
// 指定到期時間,單位為毫秒。
Expires: "1000",
};
let savedCpt;
// 填寫拷貝後的檔案完整路徑,檔案完整路徑中不能包含Bucket名稱,例如destexampleobject1.txt。
const r1 = await client.multipartUploadCopy("destexampleobject1.txt", {
// 填寫拷貝前的檔案完整路徑,檔案完整路徑中不能包含Bucket名稱,例如srcexampleobject.txt。
sourceKey: "srcexampleobject.txt",
// 填寫源Bucket名稱,例如sourcebucket。
sourceBucketName: "sourcebucket",
copyheaders: copyheaders,
});
console.log(r1);
// 填寫拷貝後的檔案完整路徑,檔案完整路徑中不能包含Bucket名稱,例如destexampleobject2.txt。
const r2 = await client.multipartUploadCopy("destexampleobject2.txt", {
// 填寫拷貝前的檔案完整路徑,檔案完整路徑中不能包含Bucket名稱,例如srcexampleobject.txt。
sourceKey: "srcexampleobject.txt",
// 填寫源Bucket名稱,例如sourcebucket。
sourceBucketName: "sourcebucket",
}, {
// 設定並行上傳的分區數量。
parallel: 4,
// 設定分區大小。
partSize: 1024 * 1024,
progress: function (p, cpt, res) {
console.log(p);
savedCpt = cpt;
console.log(cpt);
console.log(res.headers["x-oss-request-id"]);
},
headers: headers,
copyheaders: copyheaders,
});
console.log(r2);
// 填寫拷貝後的檔案完整路徑,檔案完整路徑中不能包含Bucket名稱,例如destexampleobject3.txt。
const r3 = await client.multipartUploadCopy("destexampleobject3.txt", {
// 填寫拷貝前的檔案完整路徑,檔案完整路徑中不能包含Bucket名稱,例如srcexampleobject.txt。
sourceKey: "srcexampleobject.txt",
// 填寫源Bucket名稱,例如sourcebucket。
sourceBucketName: "sourcebucket",
}, {
checkpoint: savedCpt,
progress: function (p, cpt, res) {
console.log(p);
console.log(cpt);
console.log(res.headers["x-oss-request-id"]);
},
});
console.log(r3);
} catch (e) {
console.log(e);
}
}
copyLargeObjectBetweenDifferentBuckets()
相關文檔
拷貝小檔案
關於拷貝小檔案的完整範例程式碼,請參見GitHub樣本。
關於拷貝小檔案的API介面說明,請參見CopyObject。
拷貝大檔案
關於拷貝大檔案的完整範例程式碼,請參見GitHub樣本。
關於拷貝大檔案的API介面說明,請參見UploadPartCopy。