全部產品
Search
文件中心

Object Storage Service:開啟版本控制下Object的操作

更新時間:May 23, 2025

儲存空間(Bucket)開啟版本控制後,OSS會為Bucket中所有檔案(Object)的每個版本指定唯一的ID值,且Bucket中現有Object的內容和許可權保持不變。開啟版本控制後,還能夠防止意外覆蓋或者刪除Object ,並允許查詢和恢複Object的歷史版本。

注意事項

在已開啟版本控制的Bucket中進行上傳、列舉、下載、刪除、恢複檔案等操作時:

  • OSS會維護一個目前的版本Object以及零個或多個歷史版本Object。

  • 如果在Bucket開啟版本控制前上傳了Object,則OSS將Object的版本ID值置為null。

  • 本文圖示中的版本ID均以簡短版本ID代替。

更多資訊,請參見版本控制介紹

上傳檔案

在已開啟版本控制的Bucket中上傳Object時,OSS會為這些上傳的Object自動添加唯一的版本ID。

說明

PutObject、PostObject、CopyObject 、MultipartUpload等操作都會為新產生的Object自動添加唯一的版本ID。

通過PUT操作上傳Object時,OSS會為該Object指定唯一的版本號碼(ID=111111)。

通過PUT操作第一次上傳同名Object(key=example.jpg)時,原始Object版本(ID=111111)作為歷史版本,產生的新版本(ID=222222)將作為目前的版本儲存在Bucket中。當再次上傳同名Object時,原始Object版本(包括ID=111111以及ID=222222)將作為歷史版本,而產生的新版本(ID=333333)則作為目前的版本儲存在Bucket中。

使用OSS控制台

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列,選擇文件管理>檔案清單

  4. 檔案清單頁面,單擊上傳文件

  5. 上傳文件面板,按如下說明配置各項參數。

    1. 設定基礎選項。

      參數

      說明

      上傳到

      設定檔案上傳到目標Bucket後的儲存路徑。

      • 當前目錄:將檔案上傳到目前的目錄。

      • 指定目錄:將檔案上傳到指定目錄,您需要輸入目錄名稱。如果輸入的目錄不存在,OSS將自動建立對應的檔案目錄並將檔案上傳到該目錄中。

        目錄命名規範如下:

        • 請使用符合要求的UTF-8字元;長度必須在1~254字元之間。

        • 不允許以正斜線(/)或反斜線(\)開頭。

        • 不允許出現連續的正斜線(/)。

        • 不允許出現名為 .. 的目錄。

      檔案ACL

      設定檔案讀寫權限ACL。

      • 繼承Bucket:以Bucket讀寫權限為準。

      • 私有(推薦):只有檔案Owner擁有該檔案的讀寫權限,其他使用者沒有許可權操作該檔案。

      • 公共讀:檔案Owner擁有該檔案的讀寫權限,其他使用者(包括匿名訪問者)都可以對檔案進行訪問,這有可能造成您資料的外泄以及費用激增,請謹慎操作。

      • 公共讀寫:任何使用者(包括匿名訪問者)都可以對檔案進行訪問,並且向該檔案寫入資料。這有可能造成您資料的外泄以及費用激增。如果被人惡意寫入違法資訊還可能會侵害您的合法權益。除特殊情境外,不建議您為檔案配置公用讀寫許可權。

      關於檔案ACL的更多資訊,請參見設定Object ACL

      待上傳檔案

      選擇您需要上傳的檔案或檔案夾。

      您可以單擊掃描檔案掃描文件夾選擇本地檔案或檔案夾,或者直接拖拽目標檔案或檔案夾到待上傳檔案地區。

      如果上傳檔案夾中包含了無需上傳的檔案,請單擊目標檔案操作列的移除將其移出檔案清單。

      重要
      • 在未開啟版本控制的Bucket中上傳檔案時,如果上傳的檔案與已有檔案同名,則覆蓋已有檔案。

      • 在已開啟版本控制的Bucket中上傳檔案時,如果上傳的檔案與已有檔案同名,則上傳的檔案將成為最新版本,已有檔案將成為歷史版本。

    2. 可選:單擊進階選項右側的image.png表徵圖,設定檔案儲存體類型、加密方式等進階選項。

      參數

      說明

      存儲類型

      設定檔案儲存體類型。 取值範圍如下:

      • 繼承Bucket(預設):以Bucket儲存類型為準。

      • 標準儲存提供高可靠、高可用、高效能的Object Storage Service服務,能夠支援頻繁的資料訪問。適用於各種社交、分享類的圖片、音視頻應用、大型網站、巨量資料分析等業務情境。標準儲存類型支援同城冗餘ZRS(Zone-redundant storage)和本地冗餘LRS(Locally redundant storage)兩種資料冗餘儲存方式。

      • 低頻訪問儲存提供高持久性、較低儲存成本的Object Storage Service服務。有最小計量單位(64 KB)和最低儲存時間(30天)的要求。支援資料即時訪問,訪問資料時會產生資料取回費用,適用於較低訪問頻率(平均每月訪問頻率1到2次)的業務情境。低頻訪問儲存支援同城冗餘和本地冗餘兩種資料冗餘儲存方式。

      • Archive Storage提供高持久性、極低儲存成本的Object Storage Service服務。有最小計量單位(64 KB)和最低儲存時間(60天)要求。Archive Storage資料支援解凍(約1分鐘)後訪問或直接存取。解凍後訪問會產生Archive Storage資料取回容量費用,直接存取會產生歸檔直讀資料取回容量費用。Archive Storage適用於資料長期儲存的業務情境,例如檔案資料、醫學影像、科學資料、影視素材等。Archive Storage支援同城冗餘和本地冗餘兩種資料冗餘儲存方式。

      • 冷Archive Storage提供高持久性、比Archive Storage的儲存成本更低的Object Storage Service服務。有最小計量單位(64 KB)和最低儲存時間(180天)的要求。資料需解凍後訪問,解凍時間根據資料大小和選擇的解凍模式決定,解凍會產生資料取回費用以及取回請求費用。適用於需要超長時間存放的冷資料,例如因合規要求需要長期留存的資料、巨量資料及人工智慧領域長期積累的未經處理資料、影視行業長期留存的媒體資源、線上教育行業的歸檔視頻等業務情境。冷歸檔僅支援本地冗餘的資料冗餘儲存方式。

      • 深度冷Archive Storage提供高持久性、比冷Archive Storage成本更低的Object Storage Service服務。有最小計量單位(64 KB)和最低儲存時間(180天)的要求。資料需解凍後訪問,解凍時間根據資料大小和選擇的解凍模式決定,解凍會產生資料取回費用以及取回請求費用。適用於需要超長時間存放的極冷資料,例如巨量資料及人工智慧領域的未經處理資料的長期積累留存、媒體資料的長期保留、法規和合規性存檔、磁帶替換等業務情境。深度冷歸檔僅支援本地冗餘的資料冗餘儲存方式。

      更多資訊,請參見儲存類型介紹

      服務端加密方式

      設定檔案的服務端加密方式。 取值範圍如下:

      • 繼承 Bucket(預設):以Bucket的伺服器端加密方式為準。

      • OSS完全託管:使用OSS託管的密鑰進行加密。OSS會為每個Object使用不同的密鑰進行加密,作為額外的保護,OSS會使用主要金鑰對加密金鑰本身進行加密。

      • KMS:使用KMS預設託管的CMK或指定CMK ID進行加解密操作。

        使用KMS加密方式前,需要開通KMS服務。具體操作,請參見開通Key Management Service

        KMS對應的加密金鑰說明如下:

        加密金鑰格式為<alias>(CMK ID)。其中<alias>為使用者主要金鑰的別名,CMK ID為使用者主要金鑰ID。取值範圍如下:

        • alias/acs/oss(CMK ID):使用預設託管的CMK產生不同的密鑰來加密不同的Object,並且在Object被下載時自動解密。

        • alias/<cmkname>(CMK ID):使用指定的CMK產生不同的密鑰來加密不同的Object,並將加密Object的CMK ID記錄到Object的中繼資料中,具有解密許可權的使用者下載Object時會自動解密。其中<cmkname>為建立密鑰時配置的主要金鑰可選標識。

          使用指定的CMK ID前,您需要在KMS管理主控台建立一個與Bucket處於相同地區的普通密鑰或外部金鑰。具體操作,請參見建立密鑰

      • 密碼編譯演算法僅支援AES256密碼編譯演算法。

      用戶自訂中繼資料

      用於為Object添加描述資訊。您可以添加多條自訂中繼資料(User Meta),但所有的自訂中繼資料總大小不能超過8 KB。添加自訂中繼資料時,要求參數以x-oss-meta-為首碼,並為參數賦值,例如x-oss-meta-location:hangzhou

    3. 單擊上傳文件

      此時,您可以在工作清單面板的上傳列表頁簽查看各個檔案的上傳進度。

使用阿里雲SDK

以下僅列舉常見SDK在已開啟版本控制的Bucket中簡單上傳檔案的程式碼範例。關於其他SDK簡單上傳的程式碼範例,請參見SDK簡介

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import java.io.ByteArrayInputStream;

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的完整路徑。Object完整路徑中不能包含Bucket名稱。
        String objectName = "exampledir/object";
        // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
        String region = "cn-hangzhou";

        // 建立OSSClient執行個體。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // 以上傳字串為例。
            String content = "Hello OSS";
            PutObjectResult result = ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
            // 查看此次上傳Object的VersionId。
            System.out.println("result.versionid: " + result.getVersionId());
        } 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();
            }
        }
    }
}
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,
  // yourbucketname填寫儲存空間名稱。
  bucket: 'yourbucketname'
});

async function put() {
  const result = await client.put('fileName', path.normalize('D:\\localpath\\examplefile.txt');
  console.log(result.res.headers['x-oss-version-id']); // 查看此次上傳object的版本ID。
}
put();
using System.Text;
using Aliyun.OSS;
using Aliyun.OSS.Common;

// 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名稱,例如examplebucket。
var bucketName = "examplebucket";
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
var objectName = "exampleobject.txt";
var objectContent = "More than just cloud.";
// 填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。
const string region = "cn-hangzhou";

// 建立ClientConfiguration執行個體,按照您的需要修改預設參數。
var conf = new ClientConfiguration();

// 設定v4簽名。
conf.SignatureVersion = SignatureVersion.V4;

// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
try
{
    byte[] binaryData = Encoding.ASCII.GetBytes(objectContent);
    MemoryStream requestContent = new MemoryStream(binaryData);
    // 上傳檔案。
    var result = client.PutObject(bucketName, objectName, requestContent);
    Console.WriteLine("Put object succeeded versionid : {0}", result.VersionId);
}
catch (Exception ex)
{
    Console.WriteLine("Put object failed, {0}", ex.Message);
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS帳號資訊。*/
            
    /* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* yourRegion填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。*/
    std::string Region = "yourRegion";
    /* 填寫Bucket名稱,例如examplebucket。*/
    std::string BucketName = "examplebucket";
    /* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/
    std::string ObjectName = "exampledir/exampleobject.txt";

    /* 初始化網路等資源。*/
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);
    std::shared_ptr<std::iostream> content = std::make_shared<std::stringstream>();
    *content << "test cpp sdk";
    PutObjectRequest request(BucketName, ObjectName, content);

    /* 上傳檔案。*/
    auto outcome = client.PutObject(request);

    if (outcome.isSuccess()) {
        std::cout << "versionid:" << outcome.result().VersionId() << std::endl;
    }
    else {
        /* 異常處理。*/
        std::cout << "PutObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* 釋放網路等資源。*/
    ShutdownSdk();
    return 0;
}
package main

import (
	"context"
	"flag"
	"log"
	"strings"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// 定義全域變數
var (
	region     string // 儲存地區
	bucketName string // 儲存空間名稱
	objectName string // 對象名稱
)

// init函數用於初始化命令列參數
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// 解析命令列參數
	flag.Parse()

	// 檢查bucket名稱是否為空白
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// 檢查region是否為空白
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// 檢查object名稱是否為空白
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// 定義要上傳的內容
	content := "hi oss"

	// 載入預設配置並設定憑證提供者和地區
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// 建立OSS用戶端
	client := oss.NewClient(cfg)

	// 建立上傳對象的請求
	request := &oss.PutObjectRequest{
		Bucket: oss.Ptr(bucketName),        // 儲存空間名稱
		Key:    oss.Ptr(objectName),        // 對象名稱
		Body:   strings.NewReader(content), // 要上傳的內容
	}

	// 執行上傳對象的請求
	result, err := client.PutObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to put object %v", err)
	}

	// 列印上傳對象的versionId
	log.Printf("put object result versionId:%#v\n", *result.VersionId)
}
import argparse
import requests
import alibabacloud_oss_v2 as oss

# 建立命令列參數解析器
parser = argparse.ArgumentParser(description="put object sample")
# 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加命令列參數 --bucket,表示儲存空間的名稱,必需參數
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# 添加命令列參數 --key,表示對象的名稱,必需參數
parser.add_argument('--key', help='The name of the object.', required=True)

def main():
    args = parser.parse_args()  # 解析命令列參數

    # 從環境變數中載入憑證資訊,用於身分識別驗證
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 載入SDK的預設配置,並設定憑證提供者
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    # 設定配置中的地區資訊
    cfg.region = args.region
    # 如果提供了endpoint參數,則設定配置中的endpoint
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用配置好的資訊建立OSS用戶端
    client = oss.Client(cfg)

    # 上傳本地檔案
    local_file_path = '/yourLocalFilePath/yourFileName'
    with open(local_file_path, 'rb') as file:
        data = file.read()

    # 執行上傳對象的請求,指定儲存空間名稱、對象名稱和資料內容
    result = client.put_object(oss.PutObjectRequest(
        bucket=args.bucket,
        key=args.key,
        body=data,
    ))

    # 輸出請求的結果狀態代碼、請求ID、內容MD5、ETag、CRC64校正碼和版本ID,用於檢查請求是否成功
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' content md5: {result.content_md5},'
          f' etag: {result.etag},'
          f' hash crc64: {result.hash_crc64},'
          f' version id: {result.version_id},'
    )

if __name__ == "__main__":
    main()  # 指令碼入口,當檔案被直接運行時調用main函數
<?php

// 引入自動負載檔案 載入依賴庫
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定義命令列參數描述
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located', 'required' => True], // 地區是必填項 儲存空間所在的地區
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS', 'required' => False], // 終端節點是可選項 其他服務可以用來訪問OSS的網域名稱
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // 儲存空間名稱是必填項
    "key" => ['help' => 'The name of the object', 'required' => True], // 對象名稱是必填項
];

// 產生長選項列表 用於解析命令列參數
$longopts = \array_map(function ($key) {
    return "$key:"; // 每個參數後面加冒號 表示需要值
}, array_keys($optsdesc));

// 解析命令列參數
$options = getopt("", $longopts);

// 檢查必填參數是否缺失
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help'];
        echo "Error: the following arguments are required: --$key, $help"; // 提示使用者缺少必填參數
        exit(1);
    }
}

// 擷取命令列參數值
$region = $options["region"]; // 儲存空間所在地區
$bucket = $options["bucket"]; // 儲存空間名稱
$key = $options["key"]; // 對象名稱

// 使用環境變數載入憑證資訊 AccessKeyId 和 AccessKeySecret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的預設配置
$cfg = Oss\Config::loadDefault();

// 設定憑證提供者
$cfg->setCredentialsProvider($credentialsProvider);

// 設定地區
$cfg->setRegion($region);

// 如果提供了終端節點 則設定終端節點
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]);
}

// 建立OSS用戶端執行個體
$client = new Oss\Client($cfg);

// 定義要上傳的資料內容
$data = 'Hello OSS';

// 建立上傳對象的請求對象
$request = new Oss\Models\PutObjectRequest(
                bucket: $bucket,
                key: $key,
            );

// 佈建要求體為資料流
$request->body = Oss\Utils::streamFor($data);

// 調用putObject方法上傳對象
$result = $client->putObject($request);

// 列印返回結果
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP響應狀態代碼
    'request id:' . $result->requestId . PHP_EOL . // 請求的唯一標識
    'etag:' . $result->etag . PHP_EOL // 對象的ETag值
);

使用命令列工具ossutil

關於使用ossutil在已開啟版本控制的Bucket中簡單上傳檔案的具體操作, 請參見cp(上傳檔案)

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見PutObject

列舉檔案

在已開啟版本控制的Bucket中,您可以使用GetBucketVersions(ListObjectVersions)介面擷取Object的所有版本資訊,包括刪除標記。

  • GetBucket(ListObject)介面僅返回Object的目前的版本,且目前的版本不為刪除標記。

  • 單個GetBucketVersions(ListObjectVersions)請求最多返回1000個版本Object。您可以通過發送多次請求來擷取Object的所有版本。

    例如,如果Bucket中包含兩個Key(如example.jpg和photo.jpg),且example.jpg有900個版本,photo.jpg有500個版本,則單個請求將按字母序和版本順序列舉example.jpg的900個版本和photo.jpg的100個版本。

如下圖所示,在開啟了版本控制的Bucket中,調用GetBucketVersions(ListObjectVersions)介面時,返回了Bucket中所有Object的所有版本,包含目前的版本為刪除標記的Object ;調用GetBucket(ListObject)介面時,則僅返回Object的目前的版本,且目前的版本不能為刪除標記,因此僅返回目前的版本ID為444444的Object。

使用OSS控制台

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

    當前頁面將分頁顯示該Bucket中所有Object的目前的版本。如果需要查看包含刪除標記在內的所有版本,請在檔案清單頁面單擊歷史版本右側的顯示

使用阿里雲SDK

以下僅列舉常見SDK在已開啟版本控制的Bucket中列舉檔案的程式碼範例。關於其他SDK列舉檔案的程式碼範例,請參見SDK簡介

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 {
        // 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";
        // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
        String region = "cn-hangzhou";

        // 建立OSSClient執行個體。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // 列舉包括刪除標記在內的所有Object的版本資訊。
            String nextKeyMarker = null;
            String nextVersionMarker = null;
            VersionListing versionListing = null;
            do {
                ListVersionsRequest listVersionsRequest = new ListVersionsRequest()
                        .withBucketName(bucketName)
                        .withKeyMarker(nextKeyMarker)
                        .withVersionIdMarker(nextVersionMarker);

                versionListing = ossClient.listVersions(listVersionsRequest);
                for (OSSVersionSummary ossVersion : versionListing.getVersionSummaries()) {
                    System.out.println("key name: " + ossVersion.getKey());
                    System.out.println("versionid: " + ossVersion.getVersionId());
                    System.out.println("Is latest: " + ossVersion.isLatest());
                    System.out.println("Is delete marker: " + ossVersion.isDeleteMarker());
                }

                nextKeyMarker = versionListing.getNextKeyMarker();
                nextVersionMarker = versionListing.getNextVersionIdMarker();
            } while (versionListing.isTruncated());
        } 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();
            }
        }
    }
}
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: 'yourbucketname'
});

// 列舉包括刪除標記在內的所有Object的版本資訊。
async function getObjectVersions() {
  let nextKeyMarker = null;
  let nextVersionMarker = null;
  let versionListing = null;
  do {
    versionListing = await client.getBucketVersions({
      keyMarker: nextKeyMarker,
      versionIdMarker: nextVersionMarker,
    });

    versionListing.objects.forEach((o) => {
      console.log(`${o.name}, ${o.versionId}`);
    });
    versionListing.deleteMarker.forEach((o) => {
      console.log(`${o.name}, ${o.versionId}`);
    });

    nextKeyMarker = versionListing.NextKeyMarker;
    nextVersionMarker = versionListing.NextVersionIdMarker;
  } while (versionListing.isTruncated);
}

getObjectVersions();
import argparse
import alibabacloud_oss_v2 as oss

# 建立命令列參數解析器,並描述指令碼用途:樣本展示如何列出OSS儲存空間中的對象版本
parser = argparse.ArgumentParser(description="list object versions sample")

# 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加命令列參數 --bucket,表示要操作的儲存空間名稱,必需參數
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')

def main():
    # 解析命令列提供的參數,擷取使用者輸入的值
    args = parser.parse_args()

    # 從環境變數中載入訪問OSS所需的認證資訊,用於身分識別驗證
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用SDK的預設配置建立設定物件,並設定認證提供者
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region

    # 如果提供了自訂endpoint,則更新設定物件中的endpoint屬性
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用上述配置初始化OSS用戶端,準備與OSS互動
    client = oss.Client(cfg)

    # 建立用於分頁列出對象版本的Paginator對象
    paginator = client.list_object_versions_paginator()

    # 遍曆對象版本頁面
    for page in paginator.iter_page(oss.ListObjectVersionsRequest(
            bucket=args.bucket,  # 儲存空間名
        )
    ):
        # 遍曆當前頁面中的每個對象版本
        for o in page.version:
            # 列印每個對象版本的關鍵資訊:
            # - key: 對象的鍵(名稱)
            # - size: 對象的大小(位元組數)
            # - version_id: 對象版本ID
            # - last_modified: 對象最後修改時間
            print(f'Object version: {o.key}, Size: {o.size}, Version_id: {o.version_id}, Last_modified: {o.last_modified}')


# 當此指令碼被直接執行時,調用main函數開始處理邏輯
if __name__ == "__main__":
    main()  # 指令碼進入點,控製程序流程從這裡開始

使用命令列工具ossutil

關於在已開啟版本控制的Bucket中列舉檔案的具體操作,請參見ls(列舉帳號層級下的資源)

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見ListObjectVersions(GetBucketVersions)

下載檔案

您可以在已開啟版本控制的Bucket中下載目前的版本或指定版本的Object。

通過GET請求下載Object時,未指定版本ID則返回目前的版本(ID=333333)。

如果目前的版本為刪除標記(Delete Marker),在執行GET操作時,OSS會返回404 Not Found。

通過GET請求下載Object時,指定版本ID可擷取特定版本(ID=222222)。

使用OSS控制台

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列,選擇文件管理>檔案清單

  4. 檔案清單頁面,單擊歷史版本右側的顯示

  5. 單擊指定版本的Object,在彈出的面板單擊檔案URL右側的下載

使用阿里雲SDK

以下僅列舉常見SDK在已開啟版本控制的Bucket中下載檔案的程式碼範例。關於其他SDK下載檔案的程式碼範例,請參見SDK簡介

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,
  // yourbucketname填寫儲存空間名稱。
  bucket: 'yourbucketname'
});

async function get() {
  // 檔案名稱。
  const result = await client.get('filename', {    
      // 查看下載檔案的版本ID。
      versionId: 'versionid',
  });
  console.log(result.content);
}
get();
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS帳號資訊。*/
            
    /* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* yourRegion填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。*/
    std::string Region = "yourRegion";
    /* 填寫Bucket名稱,例如examplebucket。*/
    std::string BucketName = "examplebucket";
    /* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/
    std::string ObjectName = "exampledir/exampleobject.txt";

    /* 初始化網路等資源。*/
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    /* 擷取檔案到本地記憶體。*/
    GetObjectRequest request(BucketName, ObjectName);
    request.setVersionId("yourObjectVersionId");
    auto outcome = client.GetObject(request);
    if (outcome.isSuccess()) {
        std::cout << "getObjectToBuffer" << " success, Content-Length:" << outcome.result().Metadata().ContentLength() << std::endl;
        /* 讀取下載的Object內容。*/
        std::string content;
        *(outcome.result().Content()) >> content;
        std::cout << "getObjectToBuffer" << "content:" << content << std::endl;
        /* 查看本次下載Object的版本ID。*/
        std::cout << "versionid:" << outcome.result().VersionId() << std::endl;
    }
    else {
            /* 異常處理。*/
            std::cout << "getObjectToBuffer fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* 釋放網路等資源。*/
    ShutdownSdk();
    return 0;
}
import argparse
import alibabacloud_oss_v2 as oss

# 建立命令列參數解析器
parser = argparse.ArgumentParser(description="get object sample")

# 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加命令列參數 --bucket,表示儲存空間的名稱,必需參數
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# 添加命令列參數 --key,表示對象的名稱,必需參數
parser.add_argument('--key', help='The name of the object.', required=True)
# 添加命令列參數 --version_id,表示對象的版本ID,必需參數
parser.add_argument('--version_id', help='The version ID of the object.', required=True)

def main():
    # 解析命令列參數
    args = parser.parse_args()

    # 從環境變數中載入憑證資訊,用於身分識別驗證
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 載入SDK的預設配置,並設定憑證提供者
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider

    # 設定配置中的地區資訊
    cfg.region = args.region

    # 如果提供了endpoint參數,則設定配置中的endpoint
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用配置好的資訊建立OSS用戶端
    client = oss.Client(cfg)

    # 執行擷取對象的請求,指定儲存空間名稱和對象名稱
    result = client.get_object(oss.GetObjectRequest(
        bucket=args.bucket,  # 指定儲存空間名稱
        key=args.key,  # 指定對象鍵名
        version_id=args.version_id, # 指定版本ID
    ))

    # 輸出擷取對象的結果資訊,用於檢查請求是否成功
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' content length: {result.content_length},'
          f' content range: {result.content_range},'
          f' content type: {result.content_type},'
          f' etag: {result.etag},'
          f' last modified: {result.last_modified},'
          f' content md5: {result.content_md5},'
          f' cache control: {result.cache_control},'
          f' content disposition: {result.content_disposition},'
          f' content encoding: {result.content_encoding},'
          f' expires: {result.expires},'
          f' hash crc64: {result.hash_crc64},'
          f' storage class: {result.storage_class},'
          f' object type: {result.object_type},'
          f' version id: {result.version_id},'
          f' tagging count: {result.tagging_count},'
          f' server side encryption: {result.server_side_encryption},'
          f' server side data encryption: {result.server_side_data_encryption},'
          f' next append position: {result.next_append_position},'
          f' expiration: {result.expiration},'
          f' restore: {result.restore},'
          f' process status: {result.process_status},'
          f' delete marker: {result.delete_marker},'
    )

    # 讀取對象的內容
    content = result.body.read()

    # 將內容儲存到本地檔案, 例如命名為test.txt
    with open('./test.txt', 'wb') as f:
        f.write(content)

    print(f'File saved to test.txt successfully!')

# 當此指令碼被直接運行時,調用main函數
if __name__ == "__main__":
    main()  # 指令碼入口,當檔案被直接運行時調用main函數
package main

import (
	"context"
	"flag"
	"io"
	"log"
	"os"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// 定義全域變數
var (
	region     string // 儲存地區
	bucketName string // 儲存空間名稱
	objectName string // 對象名稱
)

// init函數用於初始化命令列參數
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// 解析命令列參數
	flag.Parse()

	// 檢查bucket名稱是否為空白
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// 檢查region是否為空白
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// 檢查object名稱是否為空白
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// 定義輸出檔案路徑
	outputFile := "downloaded.file" // 替換為你希望儲存的檔案路徑

	// 載入預設配置並設定憑證提供者和地區
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// 建立OSS用戶端
	client := oss.NewClient(cfg)

	// 建立擷取對象的請求
	request := &oss.GetObjectRequest{
		Bucket:    oss.Ptr(bucketName),      // 儲存空間名稱
		Key:       oss.Ptr(objectName),      // 對象名稱
		VersionId: oss.Ptr("yourVersionId"), // 填寫實際的版本ID
	}

	// 執行擷取對象的操作並處理結果
	result, err := client.GetObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to get object %v", err)
	}
	defer result.Body.Close() // 確保在函數結束時關閉響應體

	// 一次性讀取整個檔案內容
	data, err := io.ReadAll(result.Body)
	if err != nil {
		log.Fatalf("failed to read object %v", err)
	}

	// 將內容寫入到檔案
	err = os.WriteFile(outputFile, data, 0644)
	if err != nil {
		log.Fatalf("failed to write to output file %v", err)
	}

	log.Printf("file downloaded successfully to %s", outputFile)
}
<?php

// 引入自動負載檔案,確保依賴庫能夠正確載入
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定義命令列參數的描述資訊
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地區(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 訪問網域名稱(可選)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名稱(必填)
    "key" => ['help' => 'The name of the object', 'required' => True], // 對象名稱(必填)
];

// 將參數描述轉換為getopt所需的長選項格式
// 每個參數後面加上":"表示該參數需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// 解析命令列參數
$options = getopt("", $longopts);

// 驗證必填參數是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 擷取參數的協助資訊
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填參數缺失,則退出程式
    }
}

// 從解析的參數中提取值
$region = $options["region"]; // Bucket所在的地區
$bucket = $options["bucket"]; // Bucket名稱
$key = $options["key"];       // 對象名稱

// 載入環境變數中的憑證資訊
// 使用EnvironmentVariableCredentialsProvider從環境變數中讀取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的預設配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 設定憑證提供者
$cfg->setRegion($region); // 設定Bucket所在的地區
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了訪問網域名稱,則設定endpoint
}

// 建立OSS用戶端執行個體
$client = new Oss\Client($cfg);

// 建立GetObjectRequest對象,用於擷取指定對象的內容
$request = new Oss\Models\GetObjectRequest(
                bucket: $bucket,
                key: $key,
                versionId:"yourVersionId", //填寫實際的版本號碼ID
);

// 執行擷取對象操作
$result = $client->getObject($request);

// 定義要儲存的本地檔案路徑
$localFilePath = './test/file.txt'; // 請替換為實際的檔案路徑

// 將內容寫入本地檔案
file_put_contents($localFilePath, $result->body->getContents());

// 列印擷取結果
// 輸出HTTP狀態代碼、請求ID以及對象的內容
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP狀態代碼,例如200表示成功
    'request id:' . $result->requestId . PHP_EOL  // 請求ID,用於調試或追蹤請求
);

使用命令列工具ossutil

關於使用ossutil在已開啟版本控制的Bucket中下載檔案的具體操作,請參見cp(下載檔案)

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見GetObject

刪除檔案

開啟版本控制後,您可以通過指定Object版本ID或者配置Lifecycle將Object永久刪除。如果刪除Object時未指定版本ID,則Bucket中將插入一個刪除標記(Delete Marker)作為目前的版本。

重要
  • 開啟版本控制後,如果刪除Object時未指定版本ID,預設不會刪除Object的目前的版本以及歷史版本。

  • 同一Bucket禁止同時開通OSS-HDFS服務和版本控制,否則可能導致OSS-HDFS服務異常。為確保服務穩定性,請儘快暫停版本控制,並配置生命週期規則清理刪除標記。

    具體操作,請參見同時開通OSS-HDFS服務和版本控制的Bucket如何處理?

您還可以通過生命週期規則的Expiration元素指定Object目前的版本到期,或通過NoncurrentVersionExpiration元素永久刪除非目前的版本Object。詳細說明如下

  • Expiration:應用於當前Object版本,通過添加刪除標記將目前的版本作為非目前的版本保留。

  • NoncurrentVersionExpiration:適用於非目前的版本Object,永久刪除這些Object版本,且無法恢複。

關於版本控制結合生命週期的更多資訊,請參見生命週期配置元素

以下分別說明在未指定版本ID以及指定版本ID的情況下,執行DELETE操作時Object的刪除行為。

  • 如果未指定Object的版本ID,則OSS會插入一個刪除標記作為目前的版本,該刪除標記也會有相應的唯一版本ID,但沒有相關資料和ACL等,如下圖所示(目前的版本為刪除標記,且版本ID=444444)。

  • 如果指定了Object的版本ID,則永久刪除該指定版本的Object,如下圖所示(即刪除版本ID=333333的Object)。

使用OSS控制台

為了減少儲存費用,建議您及時刪除不再需要的歷史版本Object。

警告

歷史版本Object被刪除後無法恢複,請謹慎操作。

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列,選擇文件管理>檔案清單

  4. 檔案清單頁面,單擊歷史版本右側的顯示

  5. 找到不再需要的歷史版本Object,根據實際選擇相應操作。

    • 如果要刪除的歷史版本Object為刪除標記,請直接單擊操作列的徹底刪除

    • 如果要刪除的歷史版本Object不為刪除標記,請將滑鼠移動到檔案操作列的image.png表徵圖上單擊徹底刪除

    您也可以批量選中待刪除的歷史版本,單擊頁面下方的徹底刪除

  6. 單擊確定

    您也可以通過配置生命週期規則,定期自動刪除歷史版本Object。更多資訊,請參見生命週期規則介紹

使用阿里雲SDK

以下僅列舉常見SDK在已開啟版本控制的Bucket中刪除指定版本檔案的程式碼範例。關於其他SDK刪除指定版本檔案的程式碼範例,請參見SDK簡介

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;

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的完整路徑。Object完整路徑中不能包含Bucket名稱。
        String objectName = "exampledir/object";
        String versionId  = "CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm****";
        // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
        String region = "cn-hangzhou";

        // 建立OSSClient執行個體。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // 刪除指定版本的Object。
            ossClient.deleteVersion(bucketName, objectName , versionId);
        } 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();
            }
        }
    }
}
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: 'yourbucketname'
});

// 指定Object的versionId。
const versionId = "versionId";
// 指定Object。
const objectName = "exampleobject.txt";
async function deleteVersionObject() {
  const result = await client.delete(objectName, {
    versionId,
  });
  console.log(result);
}

deleteVersionObject();
using Aliyun.OSS;
using Aliyun.OSS.Common;

// 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名稱,例如examplebucket。
var bucketName = "examplebucket";
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
var objectName = "exampledir/exampleobject.txt";
// 填寫Object的版本ID或刪除標記的版本ID。
var versionid = "yourObjectVersionidOrDelMarkerVersionid";
// 填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。
const string region = "cn-hangzhou";

// 建立ClientConfiguration執行個體,按照您的需要修改預設參數。
var conf = new ClientConfiguration();

// 設定v4簽名。
conf.SignatureVersion = SignatureVersion.V4;

// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
try
{
    // 指定Object的versionId,也可以是刪除標記的versionId。
    var request = new DeleteObjectRequest(bucketName, objectName)
    {
        VersionId = versionid
    };
    client.DeleteObject(request);
    Console.WriteLine("Delete object succeeded");
}
catch (Exception ex)
{
    Console.WriteLine("Delete object failed. {0}", ex.Message);
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS帳號資訊。*/
            
    /* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* yourRegion填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。*/
    std::string Region = "yourRegion";
    /* 填寫Bucket名稱,例如examplebucket。*/
    std::string BucketName = "examplebucket";
    /* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/
    std::string ObjectName = "exampledir/exampleobject.txt";

    /* 初始化網路等資源。*/
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    /* 刪除指定versionId的Object或指定versionId的刪除標記關聯的Object。*/
    auto outcome = client.DeleteObject(DeleteObjectRequest(BucketName, ObjectName, "yourObjectVersionIdOrDeleteMarkerVersionId"));
    /* 如果指定的是Object的versionId,則返回的delete_marker為None且返回的versionId為指定Object的versionId。*/
    /* 如果指定的是刪除標記的versionId,則返回的delete_marker為True且返回的versionId為指定刪除標記的versionId。*/
    if (!outcome.isSuccess()) {
        /* 異常處理。*/
        std::cout << "DeleteObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* 釋放網路等資源。*/
    ShutdownSdk();
    return 0;
}
package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// 定義全域變數
var (
	region     string // 儲存地區
	bucketName string // 儲存空間名稱
	objectName string // 對象名稱
)

// init函數用於初始化命令列參數
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// 解析命令列參數
	flag.Parse()

	// 檢查bucket名稱是否為空白
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// 檢查region是否為空白
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// 檢查對象名稱是否為空白
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// 載入預設配置並設定憑證提供者和地區
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// 建立OSS用戶端
	client := oss.NewClient(cfg)

	// 建立刪除對象的請求
	request := &oss.DeleteObjectRequest{
		Bucket:    oss.Ptr(bucketName),      // 儲存空間名稱
		Key:       oss.Ptr(objectName),      // 對象名稱
		VersionId: oss.Ptr("yourVersionId"), // 填寫實際的版本ID
	}

	// 執行刪除對象的操作並處理結果
	result, err := client.DeleteObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to delete object %v", err)
	}

	// 列印刪除對象的結果
	log.Printf("delete object result:%#v\n", result)
}
<?php

// 引入自動負載檔案,確保依賴庫能夠正確載入
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定義命令列參數的描述資訊
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地區(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 訪問網域名稱(可選)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名稱(必填)
    "key" => ['help' => 'The name of the object', 'required' => True], // 對象名稱(必填)
];

// 將參數描述轉換為getopt所需的長選項格式
// 每個參數後面加上":"表示該參數需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// 解析命令列參數
$options = getopt("", $longopts);

// 驗證必填參數是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 擷取參數的協助資訊
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填參數缺失,則退出程式
    }
}

// 從解析的參數中提取值
$region = $options["region"]; // Bucket所在的地區
$bucket = $options["bucket"]; // Bucket名稱
$key = $options["key"];       // 對象名稱

// 載入環境變數中的憑證資訊
// 使用EnvironmentVariableCredentialsProvider從環境變數中讀取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的預設配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 設定憑證提供者
$cfg->setRegion($region); // 設定Bucket所在的地區
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了訪問網域名稱,則設定endpoint
}

// 建立OSS用戶端執行個體
$client = new Oss\Client($cfg);

// 建立DeleteObjectRequest對象,用於刪除指定的對象
$request = new Oss\Models\DeleteObjectRequest(
            bucket: $bucket,
            key: $key,
            versionId:"yourversionid", //指定要刪除的對象版本號碼
);

// 執行刪除對象操作
$result = $client->deleteObject($request);

// 列印刪除結果
// 輸出HTTP狀態代碼和請求ID,用於驗證刪除是否成功
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP狀態代碼,例如204表示刪除成功
    'request id:' . $result->requestId . PHP_EOL     // 請求ID,用於調試或追蹤請求
);

使用命令列工具ossutil

關於使用ossutil在已開啟版本控制的Bucket中刪除檔案的具體操作, 請參見rm(刪除)

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見DeleteObject

恢複檔案

開啟版本控制後,Bucket中Object的所有版本都將得以保留。您可以通過恢複指定歷史版本的方式,使得任意Object的歷史版本成為目前的版本。

您可以通過以下兩種方式將Object的歷史版本恢複至目前的版本:

  • 通過CopyObject來恢複Object的歷史版本

    複製的Object將成為該Object的目前的版本,且所有Object版本都將保留。

    如下圖所示,將原Object的歷史版本(ID=222222)複製到同一個Bucket中,OSS將為該Object產生新的版本(ID=444444),並將其置為該Object的目前的版本。因此,該Object同時具有歷史版本(ID=222222)以及目前的版本(ID=444444)。

  • 通過刪除Object的目前的版本來恢複Object的歷史版本

    如下圖所示,當您通過DELETE versionId的方式永久刪除當前Object版本(ID=222222)後, 下一個歷史版本(ID=111111)成為了該Object的目前的版本。

重要

由於Object的目前的版本刪除後無法恢複,建議您通過CopyObject的方式來恢複Object的歷史版本。

使用OSS控制台

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列,選擇文件管理>檔案清單

  4. 檔案清單頁面,單擊歷史版本右側的顯示

  5. 將指定歷史版本的Object恢複為目前的版本。

    重要

    同一個Object僅允許恢複其中的某個歷史版本,且該歷史版本不能為刪除標記。

    • 恢複單個Object

      單擊目標歷史版本操作列的恢復

    • 恢複多個Object

      選中目標歷史版本,單擊頁面下方的恢復後,在彈出的對話方塊,單擊確定

使用阿里雲SDK

以下僅列舉常見SDK在已開啟版本控制的Bucket中拷貝指定版本檔案的程式碼範例。關於其他SDK拷貝指定版本檔案的程式碼範例,請參見SDK簡介

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 {
        // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫源Bucket名稱。
        String sourceBucketName = "srcexamplebucket";
        // 填寫源Object的完整路徑。Object完整路徑中不能包含Bucket名稱。
        String sourceObjectName = "srcexampleobject.txt";
        // 填寫與源Bucket處於同一地區的目標Bucket名稱。
        String destinationBucketName = "desexamplebucket";
        // 填寫目標Object的完整路徑。Object完整路徑中不能包含Bucket名稱。
        String destinationObjectName = "desexampleobject.txt";
        String versionId  = "CAEQMxiBgICAof2D0BYiIDJhMGE3N2M1YTI1NDQzOGY5NTkyNTI3MGYyMzJm****";
        // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
        String region = "cn-hangzhou";

        // 建立OSSClient執行個體。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName);
            copyObjectRequest.setSourceVersionId(versionId);
            CopyObjectResult copyObjectResult = ossClient.copyObject(copyObjectRequest);
            System.out.println("ETag: " + copyObjectResult.getETag() + " LastModified: " + copyObjectResult.getLastModified());
            System.out.println("dest object versionid: " + copyObjectResult.getVersionId());
        } 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();
            }
        }
    }
}
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,
  // yourbucketname填寫儲存空間名稱。
  bucket: 'yourbucketname'
});

// 指定拷貝源Object的versionId。
const versionId = 'versionId';
// 指定拷貝源Object。
const srcObject = 'srcObject.txt';
// 指定拷貝源Bucket。
const srcBucket = 'srcBucket;
// 指定拷貝目標Object。
const targetObject = 'targetObject.txt';
async function Copy() {
  try {
    const result = await client.copy(targetObject, srcObject, srcBucket, {
      meta: {
        versionId: versionId
      }
    });

    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Copy()
using Aliyun.OSS;
using Aliyun.OSS.Common;
// 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 sourceBucket = "yourSourceBucketName";
// 填寫源Object的完整路徑。Object完整路徑中不能包含Bucket名稱。
var sourceObject = "yourSourceObjectName";
// 填寫與源Bucket處於同一地區的目標Bucket名稱。
var targetBucket = "yourDestBucketName";
// 填寫目標Object的完整路徑。Object完整路徑中不能包含Bucket名稱。
var targetObject = "yourDestObjectName";
// 填寫Object的版本ID。
var versionid = "yourArchiveObjectVersionid";
// 填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。
const string region = "cn-hangzhou";

// 建立ClientConfiguration執行個體,按照您的需要修改預設參數。
var conf = new ClientConfiguration();

// 設定v4簽名。
conf.SignatureVersion = SignatureVersion.V4;

// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
try
{
    var metadata = new ObjectMetadata();
    metadata.AddHeader("mk1", "mv1");
    metadata.AddHeader("mk2", "mv2");
    var req = new CopyObjectRequest(sourceBucket, sourceObject, targetBucket, targetObject)
    {
        // 如果NewObjectMetadata為null,則為COPY模式(即拷貝源檔案的中繼資料),非null則為REPLACE模式(即覆蓋源檔案的中繼資料)。
        NewObjectMetadata = metadata, 
        // 指定Object的版本ID。
        SourceVersionId = versionid
    };
    // 拷貝檔案。
    var result = client.CopyObject(req);
    Console.WriteLine("Copy object succeeded, vesionid:{0}", result.VersionId);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID: {2} \tHostID: {3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS帳號資訊。*/
            
    /* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* yourRegion填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。*/
    std::string Region = "yourRegion";
    /* 填寫源Bucket名稱,例如srcexamplebucket。*/
    std::string SourceBucketName = "srcexamplebucket";
    /* 填寫與源Bucket處於同一地區的目標Bucket名稱,例如destbucket。*/
    std::string CopyBucketName = "destbucket";
    /* 填寫源Object的完整路徑,完整路徑中不能包含Bucket名稱,例如srcdir/scrobject.txt。*/
    std::string SourceObjectName = "srcdir/scrobject.txt";
    /* 填寫目標Object的完整路徑,完整路徑中不能包含Bucket名稱,例如destdir/destobject.txt。*/
    std::string CopyObjectName = "destdir/destobject.txt";


    /* 初始化網路等資源。*/
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    CopyObjectRequest request(CopyBucketName, CopyObjectName);
    request.setCopySource(SourceBucketName, SourceObjectName);
    /* 填寫源Object的版本ID。*/
    request.setVersionId("yourSourceObjectVersionId");

    /* 拷貝指定版本的Object。*/
    auto outcome = client.CopyObject(request);

    if (outcome.isSuccess()) {
        std::cout << "versionid:" << outcome.result().VersionId() << std::endl;
    }
    else {
        /* 異常處理。*/
        std::cout << "CopyObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* 釋放網路等資源。*/
    ShutdownSdk();
    return 0;
}
import time
import argparse
import alibabacloud_oss_v2 as oss

# 建立命令列參數解析器,並描述指令碼用途:解凍對象樣本
parser = argparse.ArgumentParser(description="restore object sample")

# 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加命令列參數 --bucket,表示儲存空間的名稱,必需參數
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# 添加命令列參數 --key,表示對象的名稱,必需參數
parser.add_argument('--key', help='The name of the object.', required=True)
# 添加命令列參數 --version_id,表示對象的版本ID,必需參數
parser.add_argument('--version_id', help='The version ID of the object.', required=True)

def main():
    # 解析命令列提供的參數,擷取使用者輸入的值
    args = parser.parse_args()

    # 從環境變數中載入訪問OSS所需的認證資訊,用於身分識別驗證
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用SDK的預設配置建立設定物件,並設定認證提供者
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    
    # 設定設定物件的地區屬性,根據使用者提供的命令列參數
    cfg.region = args.region

    # 如果提供了自訂endpoint,則更新設定物件中的endpoint屬性
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用上述配置初始化OSS用戶端,準備與OSS互動
    client = oss.Client(cfg)

    # 發送請求以解凍對象
    result = client.restore_object(oss.RestoreObjectRequest(
        bucket=args.bucket,           # 指定儲存空間名稱
        key=args.key,                 # 指定對象名稱
        version_id=args.version_id,   # 指定對象的版本ID
        restore_request=oss.RestoreRequest(
            days=1,                    # 指定解凍後對象的保留天數
            # 可選:設定冷歸檔、深度冷歸檔的解凍優先順序,可設定為:Expedited、Standard、Bulk,預設值為Standard
            # tier="Expedited",
        )
    ))

    # 列印操作結果的狀態代碼、請求ID、版本ID以及解凍優先順序等資訊,以便確認請求狀態
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' version id: {result.version_id},'
          f' restore priority: {result.restore_priority},'  # 解凍優先順序(如果有)
          )

    # 迴圈檢查對象是否已經完成解凍
    while True:
        # 擷取對象頭部資訊
        result = client.head_object(oss.HeadObjectRequest(
            bucket=args.bucket,
            key=args.key,
            version_id=args.version_id,
        ))

        # 檢查解凍狀態
        if result.restore and result.restore != 'ongoing-request="true"':
            print('restore is success')  # 解凍成功
            break
        else:
            # 暫停5秒後再次檢查
            time.sleep(5)
            print(result.restore)  # 列印當前解凍狀態

# 當此指令碼被直接執行時,調用main函數開始處理邏輯
if __name__ == "__main__":
    main()  # 指令碼進入點,控製程序流程從這裡開始
package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// 定義全域變數
var (
	region     string // 儲存地區
	bucketName string // 儲存空間名稱
	objectName string // 對象名稱
)

// init函數用於初始化命令列參數
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}

func main() {
	// 解析命令列參數
	flag.Parse()

	// 檢查bucket名稱是否為空白
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// 檢查region是否為空白
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// 檢查object名稱是否為空白
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}

	// 載入預設配置並設定憑證提供者和地區
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// 建立OSS用戶端
	client := oss.NewClient(cfg)

	// 建立解凍對象的請求
	request := &oss.RestoreObjectRequest{
		Bucket:    oss.Ptr(bucketName),      // 儲存空間名稱
		Key:       oss.Ptr(objectName),      // 對象名稱
		VersionId: oss.Ptr("yourVersionId"), //填寫實際的版本ID
		RestoreRequest: &oss.RestoreRequest{
			Days: 3, // 設定解凍狀態的持續天數為3天
		},
	}

	// 發送解凍對象的請求
	result, err := client.RestoreObject(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to restore object %v", err)
	}

	// 列印解凍對象的結果
	log.Printf("restore object result:%#v\n", result)
}
<?php

// 引入自動負載檔案,確保依賴庫能夠正確載入
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定義命令列參數的描述資訊
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地區(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 訪問網域名稱(可選)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名稱(必填)
    "key" => ['help' => 'The name of the object', 'required' => True], // 對象名稱(必填)
];

// 將參數描述轉換為getopt所需的長選項格式
// 每個參數後面加上":"表示該參數需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// 解析命令列參數
$options = getopt("", $longopts);

// 驗證必填參數是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 擷取參數的協助資訊
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填參數缺失,則退出程式
    }
}

// 從解析的參數中提取值
$region = $options["region"]; // Bucket所在的地區
$bucket = $options["bucket"]; // Bucket名稱
$key = $options["key"];       // 對象名稱

// 載入環境變數中的憑證資訊
// 使用EnvironmentVariableCredentialsProvider從環境變數中讀取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的預設配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 設定憑證提供者
$cfg->setRegion($region); // 設定Bucket所在的地區
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了訪問網域名稱,則設定endpoint
}

// 建立OSS用戶端執行個體
$client = new Oss\Client($cfg);

// 建立RestoreObjectRequest對象,用於恢複Archive Storage類型對象
$request = new Oss\Models\RestoreObjectRequest(
                bucket: $bucket,
                key: $key,
                versionId:"yourVersionId", // 填寫需要恢複的版本ID
            );

// 執行恢複對象操作
$result = $client->restoreObject($request);

// 列印恢複結果
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP狀態代碼,例如200表示成功
    'request id:' . $result->requestId . PHP_EOL     // 請求ID,用於調試或追蹤請求
);

使用命令列工具ossutil

關於使用ossutil在已開啟版本控制的Bucket中將歷史版本Object恢複為目前的版本Object的具體操作,請參見revert(恢複版本)

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見CopyObject