全部產品
Search
文件中心

Object Storage Service:通過設定HTTP頭管理OSS檔案中繼資料

更新時間:Jun 19, 2024

Object Storage Service儲存的檔案(Object)資訊包含Key、Data和Object Meta。Object Meta是對檔案的屬性描述,包括HTTP標準屬性(HTTP Header)和使用者自訂中繼資料(User Meta)兩種。您可以通過設定HTTP標準屬性來自訂HTTP請求的策略,例如檔案(Object)緩衝策略、強制下載策略等。您還可以通過設定使用者自訂中繼資料來標識Object的用途或屬性等。

HTTP標準屬性

OSS將為上傳至Bucket中的每個Object保留如下HTTP標準屬性。

名稱

描述

Content-Type

指定Object的檔案類型。內容類型決定瀏覽器將以什麼形式、什麼編碼讀取檔案。如果沒有指定檔案類型,則根據檔案的副檔名產生。如果檔案沒有副檔名,則檔案類型的預設值application/octet-stream。Content-Type的常見設定請參見如何設定Content-Type(MIME)?

Content-Encoding

聲明Object的編碼方式。您需要按照Object 的實際編碼類別型填寫,否則可能造成用戶端(瀏覽器)解析編碼失敗或Object下載失敗。若Object未編碼,請置空此項。取值如下:

  • identity(預設值):表示Object未經過壓縮或編碼。

  • gzip:表示Object採用Lempel-Ziv(LZ77)壓縮演算法以及32位CRC校正的編碼方式。

  • compress:表示Object採用Lempel-Ziv-Welch(LZW)壓縮演算法的編碼方式。

  • deflate:表示Object採用zlib結構和deflate壓縮演算法的編碼方式。

  • br:表示Object採用Brotli演算法的編碼方式。

關於Content-Encoding的更多資訊,請參見RFC2616

重要

如果您希望訪問OSS內常見網頁靜態檔案(HTML、Javascript、XML、json)時進行Gzip壓縮,您需要置空此項,並在請求中增加Accept-Encoding: gzip

Content-Language

聲明Object內容使用的語言。例如某個Object使用簡體中文編寫,則此項可設定為zh-CN

Content-Disposition

指定Object的展示形式。取值如下:

  • Content-Disposition:inline:直接預覽檔案內容。

  • Content-Disposition:attachment:以原檔案名稱的形式下載到瀏覽器指定路徑。

  • Content-Disposition:attachment; filename="yourFileName":以自訂檔案名稱的形式下載到瀏覽器指定路徑。

    yourFileName用於自訂下載後的檔案名稱,例如example.jpg。

將Object下載到瀏覽器指定路徑時:

說明
  • 如果Object名稱包含星號(*)、正斜線(/)等特殊字元時,可能會出現特殊字元轉義的情況。例如,下載example*.jpg到本地時,example*.jpg可能會轉義為example_.jpg

  • 如需確保下載名稱中包含中文字元的Object到本地指定路徑後,檔案名稱不出現亂碼的現象,您需要將名稱中包含的中文字元進行URL編碼。例如,將測試.txt從OSS下載到本地後,需要保留檔案名稱為測試.txt,需按照"attachment;filename="+URLEncoder.encode("測試","UTF-8")+".txt;filename*=UTF-8''"+URLEncoder.encode("測試","UTF-8")+".txt"的格式設定Content-Disposition,即attachment;filename=%E6%B5%8B%E8%AF%95.txt;filename*=UTF-8''%E6%B5%8B%E8%AF%95.txt

通過檔案URL訪問檔案時是預覽還是以附件形式下載,與檔案所在Bucket的建立時間、OSS開通時間以及使用的網域名稱類型有關。更多資訊,請參見通過檔案URL訪問檔案無法預覽而是以附件形式下載?

Cache-Control

指定Object的緩衝行為。取值如下:

  • no-cache:不可直接使用緩衝,而是先到服務端驗證Object是否已更新。如果Object已更新,表明緩衝已到期,需從服務端重新下載Object;如果Object未更新,表明緩衝未到期,此時將使用本機快取。

  • no-store:所有內容都不會被緩衝。

  • public:所有內容都將被緩衝。

  • private:所有內容只在用戶端緩衝。

  • max-age=<seconds>:緩衝內容的相對到期時間,單位為秒。此選項僅在HTTP 1.1中可用。

Expires

緩衝內容的絕對到期時間,格式是格林威治時間(GMT)。例如2022-10-12T00:00:00.000Z。如果Cache-Control設定了max-age=<seconds>,以max-age=<seconds>為準。

Last-Modified

Object的最後修改時間。Last-Modified由OSS自動更新,用於緩衝控制、同步和資料管理,以UTC格式表示,不可手動更改。更多資訊,請參見哪些操作會更新Object的LastModified?

說明

OSS控制台在展示檔案更新時間時,會將其從UTC時間格式轉換為本地時間格式,從而確保您在控制台上看到的時間與所處時區的本地時間一致。例如,假設檔案更新時間為2024年2月28日下午1點31分54秒,如果您所處的時區是北京時區(東八區,UTC+8),控制台會自動將時間增加8小時,展示為2024年2月28日晚上9點31分54秒。

Content-Length

Object的大小,單位為位元組。

使用者自訂中繼資料

您可以在上傳Object時,為Object添加自訂中繼資料(User Meta),用於標識Object的用途或屬性等。

  • 一個Object可以有多個自訂中繼資料,但所有的自訂中繼資料總大小不能超過8 KB。

  • 自訂中繼資料是一組索引值對,中繼資料名稱必須以x-oss-meta-開頭。例如x-oss-meta-last-modified:20210506,可用於記錄本地檔案最後修改時間為2021年5月6日。

  • 調用GetObject或者HeadObject介面時,將在HTTP頭部返回自訂中繼資料。

操作步驟

使用OSS控制台

通過OSS管理主控台一次可批量為100個Object設定檔案中繼資料。

  1. 登入OSS管理主控台

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

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

  4. 設定HTTP標準屬性以及使用者自訂中繼資料。

    • 設定多個Object的HTTP頭

      選中一個或多個Object,然後單擊下方的設定檔案中繼資料

    • 設定單個Object的HTTP頭

      在目標Object右側選擇more > 設定檔案中繼資料

  5. 單擊確定

使用圖形化管理工具ossbrowser

ossbrowser支援Object層級的操作與控制台支援的操作類似,請按照ossbrowser介面指引完成設定Object中繼資料的操作。關於如何使用ossbrowser,請參見快速使用ossbrowser

使用阿里雲SDK

以下僅列舉常見SDK的設定Object中繼資料的程式碼範例。關於其他SDK的設定Object中繼資料的程式碼範例,請參見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.common.utils.BinaryUtil;
import com.aliyun.oss.common.utils.DateUtil;
import com.aliyun.oss.model.ObjectMetadata;
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";
        // 填寫不包含Bucket名稱在內的Object完整路徑,例如testfolder/exampleobject.txt。
        String objectName = "testfolder/exampleobject.txt";
        String content = "Hello OSS";

        // 建立OSSClient執行個體。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            // 建立上傳檔案的中繼資料。
            ObjectMetadata meta = new ObjectMetadata();

            String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes()));
            // 開啟檔案內容MD5校正。開啟後OSS會把您提供的MD5與檔案的MD5比較,不一致則拋出異常。
            meta.setContentMD5(md5);
            // 指定上傳的內容類型。內容類型決定瀏覽器將以什麼形式、什麼編碼讀取檔案。如果沒有指定則根據檔案的副檔名產生,如果沒有副檔名則為預設值application/octet-stream。
            meta.setContentType("text/plain");
            // 設定內容被下載時的名稱。
            meta.setContentDisposition("attachment; filename=\"DownloadFilename\"");
            // 設定上傳檔案的長度。如超過此長度,則上傳檔案會被截斷,上傳的檔案長度為設定的長度。如小於此長度,則為上傳檔案的實際長度。
            meta.setContentLength(content.length());
            // 設定內容被下載時網頁的緩衝行為。
            meta.setCacheControl("Download Action");
            // 設定緩衝到期時間,格式是格林威治時間(GMT)。
            meta.setExpirationTime(DateUtil.parseIso8601Date("2022-10-12T00:00:00.000Z"));
            // 設定內容被下載時的編碼格式。
            meta.setContentEncoding("gzip");
            // 設定Header。
            meta.setHeader("yourHeader", "yourHeaderValue");

            // 上傳檔案。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()), meta);
        } 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();
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "yourEndpoint";
// 填寫Bucket名稱,例如examplebucket。
$bucket= "examplebucket";
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
$object = "exampledir/exampleobject.txt";
$content = file_get_contents(__FILE__);
$options = array(
    OssClient::OSS_HEADERS => array(
        'Expires' => '2012-10-01 08:00:00',
        'Content-Disposition' => 'attachment; filename="xxxxxx"',
        'x-oss-meta-self-define-title' => 'user define meta info',
    ));
try{
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);
    // 上傳檔案時設定中繼資料。
    $ossClient->putObject($bucket, $object, $content, $options);
} 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名稱。
  bucket: 'examplebucket'
});

async function put() {
  try {
    let meta = { year: 2016, people: 'mary' };
    let result = await client.put('object-name', path.normalize('D:\\localpath\\examplefile.txt'), meta);
  console.log(result);
  } catch (e) {
    console.log(e);
  }
}

put();
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')

# 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
object_name = 'exampledir/exampleobject.txt'
# 填寫待上傳的字串。
content = '{"age": 1}'
# 設定HTTP header,例如HTTP header的名稱為Content-Type,值為'application/json; charset=utf-8'。
bucket.put_object(object_name, content, headers={'Content-Type': 'application/json; charset=utf-8'})
using Aliyun.OSS;
using Aliyun.OSS.Common;
using Aliyun.OSS.Util;

// 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";
// 填寫本地檔案的完整路徑。如果未指定本地路徑,則預設從樣本程式所屬專案對應本地路徑中上傳檔案。
var localFilename = "D:\\localpath\\examplefile.txt";
// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        // 建立上傳檔案的中繼資料,可以通過檔案中繼資料設定HTTP header。
        var metadata = new ObjectMetadata()
        {
            // 指定檔案類型。
            ContentType = "text/html",
            // 設定緩衝到期時間,格式是格林威治時間(GMT)。
            ExpirationTime = DateTime.Parse("2025-10-12T00:00:00.000Z"),
        };
        // 設定上傳檔案的長度。如超過此長度,則會被截斷為設定的長度。如不足,則為上傳檔案的實際長度。
        metadata.ContentLength = fs.Length;
        // 設定檔案被下載時網頁的緩衝行為。
        metadata.CacheControl = "No-Cache";
        // 設定中繼資料mykey1值為myval1。
        metadata.UserMetadata.Add("mykey1", "myval1");
        // 設定中繼資料mykey2值為myval2。
        metadata.UserMetadata.Add("mykey2", "myval2");
        var saveAsFilename = "檔案名稱測試123.txt";
        var contentDisposition = string.Format("attachment;filename*=utf-8''{0}", HttpUtils.EncodeUri(saveAsFilename, "utf-8"));
        // 把請求所得的內容存為一個檔案的時候提供一個預設的檔案名稱。
        metadata.ContentDisposition = contentDisposition;
        // 上傳檔案並設定檔案中繼資料。
        client.PutObject(bucketName, objectName, fs, metadata);
        Console.WriteLine("Put object succeeded");
        // 擷取檔案中繼資料。
        var oldMeta = client.GetObjectMetadata(bucketName, objectName);
        // 設定新的檔案中繼資料。
        var newMeta = new ObjectMetadata()
        {
            ContentType = "application/octet-stream",
            ExpirationTime = DateTime.Parse("2035-11-11T00:00:00.000Z"),
            // 指定檔案被下載時的內容編碼格式。
            ContentEncoding = null,
            CacheControl = ""
        };
        // 增加自訂中繼資料。
        newMeta.UserMetadata.Add("author", "oss");
        newMeta.UserMetadata.Add("flag", "my-flag");
        newMeta.UserMetadata.Add("mykey2", "myval2-modified-value");
        // 通過ModifyObjectMeta方法修改檔案中繼資料。
        client.ModifyObjectMeta(bucketName, objectName, newMeta);
    }
}
catch (Exception ex)
{
    Console.WriteLine("Put object failed, {0}", ex.Message);
}
// 建立同步擷取檔案中繼資料請求。
// 依次填寫Bucket名稱(例如examplebucket)和Object完整路徑(例如exampledir/exampleobject.txt)。Object完整路徑中不能包含Bucket名稱。
HeadObjectRequest head = new HeadObjectRequest("examplebucket", "exampledir/exampleobject.txt");

// 擷取檔案中繼資料。
OSSAsyncTask task = oss.asyncHeadObject(head, new OSSCompletedCallback<HeadObjectRequest, HeadObjectResult>() {
    @Override
    public void onSuccess(HeadObjectRequest request, HeadObjectResult result) {
    
    // 擷取檔案長度。
        Log.d("headObject", "object Size: " + result.getMetadata().getContentLength()); 
    // 擷取檔案類型。
        Log.d("headObject", "object Content Type: " + result.getMetadata().getContentType()); 
    }

    @Override
    public void onFailure(HeadObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // 請求異常。
        if (clientExcepion != null) {
            // 本地異常,如網路異常等。
            clientExcepion.printStackTrace();
        }
        if (serviceException != null) {
            // 服務異常。
            Log.e("ErrorCode", serviceException.getErrorCode());
            Log.e("RequestId", serviceException.getRequestId());
            Log.e("HostId", serviceException.getHostId());
            Log.e("RawMessage", serviceException.getRawMessage());
        }
    }
});

// task.waitUntilFinished(); //等待任務完成。
package main

import (
    "fmt"
    "os"
    "time"
    "strings"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

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名稱,例如examplebucket。
    bucket, err := client.Bucket("examplebucket")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 設定檔案中繼資料,例如指定到期時間為2049年01月10日 23:00:00 GMT,存取權限為公用讀取,自訂中繼資料為MyProp(取值MyPropVal)。
    expires := time.Date(2049, time.January, 10, 23, 0, 0, 0, time.UTC)
    options := []oss.Option{
        oss.Expires(expires),
        oss.ObjectACL(oss.ACLPublicRead),
        oss.Meta("MyProp", "MyPropVal"),
    }

    // 使用資料流上傳檔案。
    // 填寫Object的完整路徑,完整路徑中不包含Bucket名稱,例如exampledir/exampleobject.txt。
    err = bucket.PutObject("exampledir/exampleobject.txt", strings.NewReader("MyObjectValue"), options...)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 擷取檔案中繼資料。
    props, err := bucket.GetObjectDetailedMeta("exampledir/exampleobject.txt")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    fmt.Println("Object Meta:", props)
}           
OSSHeadObjectRequest * request = [OSSHeadObjectRequest new];
// 填寫Bucket名稱,例如examplebucket。
request.bucketName = @"examplebucket";
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
request.objectKey = @"exampledir/exampleobject.txt";

OSSTask * headTask = [client headObject:request];

[headTask continueWithBlock:^id(OSSTask *task) {
    if (!task.error) {
        NSLog(@"head object success!");
        OSSHeadObjectResult * result = task.result;
        NSLog(@"header fields: %@", result.httpResponseHeaderFields);
        for (NSString * key in result.objectMeta) {
            NSLog(@"ObjectMeta: %@ - %@", key, [result.objectMeta objectForKey:key]);
        }
    } else {
        NSLog(@"head object failed, error: %@" ,task.error);
    }
    return nil;
}];
#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";
    /* 填寫Bucket名稱,例如examplebucket。*/
    std::string BucketName = "examplebucket";
    /* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/
    std::string ObjectName = "exampledir/exampleobject.txt";

    /* 初始化網路等資源。*/
    InitializeSdk();
  
    ClientConfiguration conf;
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);

    /* 設定HTTP header。*/
    auto meta = ObjectMetaData();
    meta.setContentType("text/plain");
    meta.setCacheControl("max-age=3");
    /* 設定自訂檔案中繼資料。*/
    meta.UserMetaData()["meta"] = "meta-value";

    std::shared_ptr<std::iostream> content = std::make_shared<std::stringstream>();
    *content << "Thank you for using Aliyun Object Storage Service!";
    auto outcome = client.PutObject(BucketName, ObjectName, content, meta);

    if (!outcome.isSuccess()) {
        /* 異常處理。*/
        std::cout << "PutObject 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";
const char *object_content= "hello world";
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。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_table_t *headers;
    aos_list_t buffer;
    aos_table_t *resp_headers = NULL; 
    aos_status_t *resp_status = NULL; 
    aos_buf_t *content = NULL;
    char *content_length_str = NULL;
    char *object_type = NULL;
    char *object_author = NULL;
    int64_t content_length = 0;
    aos_str_set(&bucket, bucket_name);
    aos_str_set(&object, object_name);
    headers = aos_table_make(pool, 2);
    /* 設定使用者自訂中繼資料。*/
    apr_table_set(headers, "Expires", "Fri, 28 Feb 2032 05:38:42 GMT"); 
    apr_table_set(headers, "x-oss-meta-author", "oss");
    aos_list_init(&buffer);
    content = aos_buf_pack(oss_client_options->pool, object_content, strlen(object_content));
    aos_list_add_tail(&content->node, &buffer);
    /* 從緩衝中上傳檔案。*/
    resp_status = oss_put_object_from_buffer(oss_client_options, &bucket, &object, 
               &buffer, headers, &resp_headers);
    if (aos_status_is_ok(resp_status)) {
        printf("put object from buffer with md5 succeeded\n");
    } else {
        printf("put object from buffer with md5 failed\n");
    }
    /* 擷取檔案中繼資料。*/
    resp_status = oss_get_object_meta(oss_client_options, &bucket, &object, &resp_headers);
    if (aos_status_is_ok(resp_status)) {
        content_length_str = (char*)apr_table_get(resp_headers, OSS_CONTENT_LENGTH);
        if (content_length_str != NULL) {
            content_length = atol(content_length_str);
        }
        object_author = (char*)apr_table_get(resp_headers, OSS_AUTHORIZATION);
        object_type = (char*)apr_table_get(resp_headers, OSS_OBJECT_TYPE);
        printf("get object meta succeeded, object author:%s, object type:%s, content_length:%ld\n", object_author, object_type, content_length);
    } else {
        printf("req:%s, get object meta failed\n", resp_status->req_id);
    }
    /* 釋放記憶體池,相當於釋放了請求過程中各資源分派的記憶體。*/
    aos_pool_destroy(pool);
    /* 釋放之前分配的全域資源。*/
    aos_http_io_deinitialize();
    return 0;
}
require 'aliyun/oss'
client = Aliyun::OSS::Client.new(
  # 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
  endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
  # 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  access_key_id: ENV['OSS_ACCESS_KEY_ID'],
  access_key_secret: ENV['OSS_ACCESS_KEY_SECRET']
)

# 填寫Bucket名稱,例如examplebucket。
bucket = client.get_bucket('examplebucket')

# 簡單上傳時設定檔案中繼資料。
bucket.put_object(
  'my-object-1',
  :file => 'local-file',
  :metas => {'year' => '2016', 'people' => 'mary'})

# 追加上傳時設定檔案中繼資料。
bucket.append_object(
  'my-object-2', 0,
  :file => 'local-file',
  :metas => {'year' => '2016', 'people' => 'mary'})

# 斷點續傳上傳時設定檔案中繼資料。
bucket.resumable_upload(
  'my-object',
  'local-file',
  :metas => {'year' => '2016', 'people' => 'mary'})          

使用命令列工具ossutil

關於使用ossutil設定Object中繼資料的具體操作,請參見set-meta(管理檔案中繼資料)

使用REST API

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