本文中含有需要您注意的重要提示信息,忽略該信息可能對您的業務造成影響,請務必仔細閱讀。
進行分片上傳時,文件(Object)會被切成若干個Part,這些Part被稱為碎片。當您將這些Part上傳到OSS服務端后,可以調用CompleteMultipartUpload將這些碎片(Part)組合成一個完整的Object。
背景信息
使用支持斷點續傳的OSS管理工具傳輸文件時,也會產生Part。
Part在完成Object組合前,不能被讀取。刪除Bucket時,必須先刪除Object和Part。
警告Bucket和Object刪除后無法恢復,請謹慎操作。
除通過OSS控制臺、SDK、ossutil命令行等工具手動刪除Part以外,您還可以通過設置生命周期管理自動清理Bucket中長時間未執行CompleteMultipartUpload操作的Part,減少空間占用。具體操作請參見清理過期碎片。
費用說明
對于分片上傳過程中產生的Part,OSS會根據Part的存儲類型、實際大小和時長收取存儲費用。
Part的存儲類型與Object的存儲類型一致,但是Part無最小計量限制。即某個Part小于64 KB,仍然按照Part的實際大小計算。
關于Part存儲費用的更多信息,請參見存儲費用。
建議您及時完成分片上傳或者取消分片上傳,原因是已上傳但未完成或未取消的分片會占用存儲空間進而產生存儲費用。
操作步驟
使用OSS控制臺
登錄OSS管理控制臺。
單擊Bucket 列表,然后單擊目標Bucket名稱。
在左側導航欄,選擇文件管理>文件列表。
在文件列表頁面,單擊碎片管理。
在碎片管理(Multipart)面板,刪除碎片文件。
如果要刪除該存儲空間所有的碎片文件,單擊刪除所有。
如果要刪除部分碎片文件,請選中或搜索碎片文件,然后單擊刪除。
在彈出的對話框中,單擊確定。
使用圖形化管理工具ossbrowser
ossbrowser支持Object級別的操作與控制臺支持的操作類似,請按照ossbrowser界面指引完成刪除碎片的操作。關于如何使用ossbrowser,請參見快速使用ossbrowser。
使用阿里云SDK
以下僅列舉常見SDK的清理碎片代碼示例。關于其他SDK的清理碎片代碼示例,請參見SDK簡介。
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
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 {
// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫uploadId,例如0004B999EF518A1FE585B0C9360D****。uploadId來源于調用InitiateMultipartUpload完成初始化分片之后的返回結果。
String uploadId = "0004B999EF518A1FE585B0C9360D****";
// 創建OSSClient實例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// 取消分片上傳。
AbortMultipartUploadRequest abortMultipartUploadRequest =
new AbortMultipartUploadRequest(bucketName, objectName, uploadId);
ossClient.abortMultipartUpload(abortMultipartUploadRequest);
} 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();
}
}
}
}
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
$endpoint = 'https://oss-cn-hangzhou.aliyuncs.com';
// 填寫Bucket名稱,例如examplebucket。
$bucket= 'examplebucket';
//填寫不包含Bucket名稱在內的Object完整路徑,例如exampledir/exampleobject.txt。
$object = 'exampledir/exampleobject.txt';
// 填寫uploadId,例如0004B999EF518A1FE585B0C9360D****。uploadId來源于調用InitiateMultipartUpload完成初始化分片之后的返回結果。
$upload_id = '0004B999EF518A1FE585B0C9360D****';
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
);
$ossClient = new OssClient($config);
$ossClient->abortMultipartUpload($bucket, $object, $upload_id);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
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,
// 填寫存儲空間名稱。
bucket: "yourbucketname",
});
async function abortMultipartUpload() {
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
const name = "exampledir/exampleobject.txt";
// 填寫uploadId。uploadId來源于調用InitiateMultipartUpload完成初始化分片之后的返回結果。
const uploadId = "0004B999EF518A1FE585B0C9360D****";
const result = await client.abortMultipartUpload(name, uploadId);
console.log(result);
}
abortMultipartUpload();
# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
# 填寫Bucket名稱,例如examplebucket。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
# 填寫不能包含Bucket名稱在內的Object完整路徑,例如exampledir/exampleobject.txt。
key = 'exampledir/exampleobject.txt'
# 填寫upload_id。upload_id來源于調用InitiateMultipartUpload完成初始化分片之后的返回結果。
upload_id = 'yourUploadId'
# 取消指定upload_id的分片上傳事件,已上傳的分片會被刪除。
bucket.abort_multipart_upload(key, upload_id)
using Aliyun.OSS;
// yourEndpoint填寫Bucket所在地域對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填寫Bucket名稱。
var bucketName = "examplebucket";
// 填寫Object完整路徑。Object完整路徑中不能包含Bucket名稱。
var objectName = "exampleobject.txt";
// 填寫uploadId。uploadId來源于調用InitiateMultipartUpload完成初始化分片之后的返回結果。
var uploadId = "yourUploadId";
// 創建OssClient實例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
// 初始化分片上傳。
try
{
var request = new InitiateMultipartUploadRequest(bucketName, objectName);
var result = client.InitiateMultipartUpload(request);
uploadId = result.UploadId;
// 打印uploadId。
Console.WriteLine("Init multi part upload succeeded");
Console.WriteLine("Upload Id:{0}", result.UploadId);
}
catch (Exception ex)
{
Console.WriteLine("Init multi part upload failed, {0}", ex.Message);
}
// 取消分片上傳。
try
{
var request = new AbortMultipartUploadRequest(bucketName, objectName, uploadId);
client.AbortMultipartUpload(request);
Console.WriteLine("Abort multi part succeeded, {0}", uploadId);
}
catch (Exception ex)
{
Console.WriteLine("Abort multi part failed, {0}", ex.Message);
}
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫uploadId。uploadId來源于調用InitiateMultipartUpload完成初始化分片之后的返回結果。
String uploadId = "0004B999EF518A1FE585B0C9****";
// 取消分片上傳。
AbortMultipartUploadRequest abort = new AbortMultipartUploadRequest(bucketName, objectName, uploadId);
AbortMultipartUploadResult abortResult = oss.abortMultipartUpload(abort);
package main
import (
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"os"
)
func main() {
// 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 創建OSSClient實例。
// yourEndpoint填寫Bucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 填寫Bucket名稱。
bucket, err := client.Bucket("examplebucket")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 初始化一個分片上傳事件。
// 填寫Object完整路徑。Object完整路徑中不能包含Bucket名稱。
imur, err := bucket.InitiateMultipartUpload("exampleobject.txt")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 取消分片上傳。
err = bucket.AbortMultipartUpload(imur)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
}
OSSAbortMultipartUploadRequest * abort = [OSSAbortMultipartUploadRequest new];
// 填寫Bucket名稱,例如examplebucket。
abort.bucketName = @"examplebucket";
// 填寫文件完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
abort.objectKey = @"exampledir/exampleobject.txt";
// 填寫uploadId。uploadId來源于調用InitiateMultipartUpload完成初始化分片之后的返回結果。
abort.uploadId = @"0004B999EF518A1FE585B0C9****";
OSSTask * abortTask = [client abortMultipartUpload:abort];
[abortTask waitUntilFinished];
if (!abortTask.error) {
OSSAbortMultipartUploadResult * result = abortTask.result;
uploadId = result.uploadId;
} else {
NSLog(@"multipart upload failed, error: %@", abortTask.error);
return;
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* 初始化OSS賬號信息 */
std::string Endpoint = "yourEndpoint";
/* 填寫Bucket名稱,例如examplebucket */
std::string BucketName = "examplebucket";
/* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。 */
std::string ObjectName = "exampledir/exampleobject.txt";
/* 填寫UploadId。UploadId來源于調用InitiateMultipartUpload完成初始化分片之后的返回結果。*/
std::string UploadId = "yourUploadId";
/* 初始化網絡等資源 */
InitializeSdk();
ClientConfiguration conf;
/* 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
/* 初始化分片上傳事件 */
auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
auto uploadId = uploadIdResult.result().UploadId();
/* 取消分片上傳 */
AbortMultipartUploadRequest abortUploadRequest(BucketName, ObjectName, uploadId);
auto outcome = client.AbortMultipartUpload(abortUploadRequest);
if (!outcome.isSuccess()) {
/* 異常處理 */
std::cout << "AbortMultipartUpload fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
/* 釋放網絡等資源 */
ShutdownSdk();
return 0;
}
#include "oss_api.h"
#include "aos_http_io.h"
/* yourEndpoint填寫Bucket所在地域對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
const char *endpoint = "yourEndpoint";
/* 填寫Bucket名稱,例如examplebucket。*/
const char *bucket_name = "examplebucket";
/* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/
const char *object_name = "exampledir/exampleobject.txt";
void init_options(oss_request_options_t *options)
{
options->config = oss_config_create(options->pool);
/* 用char*類型的字符串初始化aos_string_t類型。*/
aos_str_set(&options->config->endpoint, endpoint);
/* 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
/* 是否使用CNAME訪問OSS服務。0表示不使用。*/
options->config->is_cname = 0;
/* 設置網絡相關參數,比如超時時間等。*/
options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
/* 在程序入口調用aos_http_io_initialize方法來初始化網絡、內存等全局資源。*/
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
exit(1);
}
/* 用于內存管理的內存池(pool),等價于apr_pool_t。其實現代碼在apr庫中。*/
aos_pool_t *pool;
/* 重新創建一個內存池,第二個參數是NULL,表示沒有繼承其它內存池。*/
aos_pool_create(&pool, NULL);
/* 創建并初始化options,該參數包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全局配置信息。*/
oss_request_options_t *oss_client_options;
/* 在內存池中分配內存給options。*/
oss_client_options = oss_request_options_create(pool);
/* 初始化Client的選項oss_client_options。*/
init_options(oss_client_options);
/* 初始化參數。*/
aos_string_t bucket;
aos_string_t object;
aos_string_t upload_id;
aos_table_t *headers = NULL;
aos_table_t *resp_headers = NULL;
aos_status_t *resp_status = NULL;
aos_str_set(&bucket, bucket_name);
aos_str_set(&object, object_name);
aos_str_null(&upload_id);
/* 初始化分片上傳,獲取一個上傳ID(upload_id)。*/
resp_status = oss_init_multipart_upload(oss_client_options, &bucket, &object, &upload_id, headers, &resp_headers);
/* 判斷是否初始化分片上傳成功。 */
if (aos_status_is_ok(resp_status)) {
printf("Init multipart upload succeeded, upload_id:%.*s\n",
upload_id.len, upload_id.data);
} else {
printf("Init multipart upload failed, upload_id:%.*s\n",
upload_id.len, upload_id.data);
}
/* 取消這次分片上傳。*/
resp_status = oss_abort_multipart_upload(oss_client_options, &bucket, &object, &upload_id, &resp_headers);
/* 判斷取消分片上傳是否成功。*/
if (aos_status_is_ok(resp_status)) {
printf("Abort multipart upload succeeded, upload_id::%.*s\n",
upload_id.len, upload_id.data);
} else {
printf("Abort multipart upload failed\n");
}
/* 釋放內存池,相當于釋放了請求過程中各資源分配的內存。*/
aos_pool_destroy(pool);
/* 釋放之前分配的全局資源。*/
aos_http_io_deinitialize();
return 0;
}
使用命令行工具ossutil
關于使用ossutil刪除Part的更多信息,請參見刪除Part。
使用REST API
如果您的程序自定義要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多信息,請參見AbortMultipartUpload