全部產品
Search
文件中心

Object Storage Service:類檔案唯讀(Python SDK V2)

更新時間:Jul 31, 2025

本文介紹如何使用Python SDK V2新增的File-Like介面訪問儲存空間的對象。

注意事項

  • 本文範例程式碼以華東1(杭州)的地區IDcn-hangzhou為例,預設使用外網Endpoint,如果您希望通過與OSS同地區的其他阿里雲產品訪問OSS,請使用內網Endpoint。關於OSS支援的Region與Endpoint的對應關係,請參見OSS地區和訪問網域名稱

  • 本文以從環境變數讀取存取憑證為例。如何配置訪問憑證,請參見配置訪問憑證

  • 要進行檔案下載,您必須有oss:GetObject許可權。具體操作,請參見為RAM使用者授予自訂的權限原則

方法定義

Python SDK V2新增了File-Like介面,以唯讀檔案(ReadOnlyFile)的方式訪問儲存空間的對象。

  • 提供了單流和並發+預取兩種模式,您可以根據情境需要調整並發數,以提升讀取速度。

  • 介面內部實現了串連斷掉重連的機制,在一些比較複雜的網路環境下,具備更好的魯棒性。

class ReadOnlyFile:
    ...


def open_file(self, bucket: str, key: str, version_id: Optional[str] = None, request_payer: Optional[str] = None, **kwargs) -> ReadOnlyFile:
    ...

請求參數列表

參數名

類型

說明

bucket

str

設定儲存空間名字

key

str

設定對象名

version_id

str

指定對象的版本號碼,多版本下有效

request_payer

str

啟用了要求者付費模式時,需要設定為'requester'

**kwargs

Any

(可選)任意參數,類型為字典

其中,kwargs選項說明列舉如下:

參數名

類型

說明

enable_prefetch

bool

是否啟用預模數式,預設不啟用

prefetch_num

int

預取塊的數量,預設值為3。啟用預模數式時有效

chunk_size

int

每個預取塊的大小,預設值為6MiB。啟用預模數式時有效

prefetch_threshold

int

持續順序讀取多少位元組後進入到預模數式,預設值為20MiB。啟用預模數式時有效

block_size

int

塊的大小,預設值為None

傳回值列表

傳回值名

類型

說明

file

ReadOnlyFile

唯讀檔案的執行個體

其中,ReadOnlyFile介面的常用方法列舉如下:

方法名

說明

close(self)

關閉檔案控制代碼,釋放資源,例如記憶體,活動的socket 等

read(self, n=None)

從資料來源中讀取長度為len(p)的位元組,儲存到p中,返回讀取的位元組數和遇到的錯誤

seek(self, pos, whence=0)

用於設定下一次讀或寫的位移量。其中whence的取值:0:相對於頭部,1:相對於當前位移量,2:相對於尾部

Stat() (os.FileInfo, error)

擷取對象的資訊,包括 對象大小,最後修改時間 以及元資訊

重要

注意:當預模數式開啟時,如果出現多次亂序讀時,則會自動退回單流模式。

範例程式碼

以單流模式讀取整個對象

import argparse
import alibabacloud_oss_v2 as oss

# 建立命令列參數解析器,用於接收使用者輸入的參數
parser = argparse.ArgumentParser(description="open file 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()

    # 從環境變數中載入憑證資訊(AccessKeyId 和 AccessKeySecret)
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 載入 SDK 的預設配置
    cfg = oss.config.load_default()

    # 設定憑證提供者
    cfg.credentials_provider = credentials_provider

    # 設定儲存空間所在的地區
    cfg.region = args.region

    # 如果使用者提供了自訂的 endpoint,則設定到配置中
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用設定物件初始化 OSS 用戶端
    client = oss.Client(cfg)

    # 調用 open_file 方法開啟儲存空間中的檔案對象
    result = client.open_file(
        bucket=args.bucket,          # 指定目標儲存空間的名稱
        key=args.key,                # 指定目標對象的名稱(檔案路徑)
    )

    # 列印檔案內容,讀取檔案資料並解碼為字串格式
    print(f'content: {result.read().decode()}')

    # 關閉檔案對象,釋放資源
    result.close()


if __name__ == "__main__":
    # 程式入口,調用 main 函數執行邏輯
    main()

啟用預模數式讀取整個對象

import argparse
import alibabacloud_oss_v2 as oss

# 建立命令列參數解析器,用於接收使用者輸入的參數
parser = argparse.ArgumentParser(description="open file 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()

    # 從環境變數中載入憑證資訊(AccessKeyId 和 AccessKeySecret)
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 載入 SDK 的預設配置
    cfg = oss.config.load_default()

    # 設定憑證提供者
    cfg.credentials_provider = credentials_provider

    # 設定儲存空間所在的地區
    cfg.region = args.region

    # 如果使用者提供了自訂的 endpoint,則設定到配置中
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用設定物件初始化 OSS 用戶端
    client = oss.Client(cfg)

    # 調用 open_file 方法開啟儲存空間中的檔案對象
    result = client.open_file(
        bucket=args.bucket,          # 指定目標儲存空間的名稱
        key=args.key,                # 指定目標對象的名稱(檔案路徑)
        enable_prefetch=True,        # 是否啟用預取功能,預設為 True
   )

    # 列印檔案內容,讀取檔案資料並解碼為字串格式
    print(f'content: {result.read().decode()}')

    # 關閉檔案對象,釋放資源
    result.close()


if __name__ == "__main__":
    # 程式入口,調用 main 函數執行邏輯
    main()

通過Seek方法從指定位置開始讀取剩餘的資料

import argparse
import os
import io
import alibabacloud_oss_v2 as oss

# 建立命令列參數解析器,用於接收使用者輸入的參數
parser = argparse.ArgumentParser(description="open file 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()

    # 從環境變數中載入憑證資訊(AccessKeyId 和 AccessKeySecret)
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 載入 SDK 的預設配置
    cfg = oss.config.load_default()

    # 設定憑證提供者
    cfg.credentials_provider = credentials_provider

    # 設定儲存空間所在的地區
    cfg.region = args.region

    # 如果使用者提供了自訂的 endpoint,則設定到配置中
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用設定物件初始化 OSS 用戶端
    client = oss.Client(cfg)

    # 初始化一個唯讀檔案對象
    rf: oss.ReadOnlyFile = None

    # 使用 with 語句開啟 OSS 檔案對象,確保檔案操作完成後自動關閉資源
    with client.open_file(args.bucket, args.key) as f:
        rf = f  # 將檔案對象賦值給 rf 變數

        # 移動檔案指標到指定位置(位移量為 1 位元組,相對於檔案開頭)
        f.seek(1, os.SEEK_SET)

        # 將檔案內容讀取到記憶體中的位元組流(BytesIO)中
        copied_stream = io.BytesIO(rf.read())

        # 列印寫入位元組流的資料長度
        print(f'written: {len(copied_stream.getvalue())}')

        # 列印讀取到的內容(位元組流會被解碼為字串格式)
        print(f'read: {copied_stream.getvalue()}')


if __name__ == "__main__":
    # 程式入口,調用 main 函數執行邏輯
    main()

相關文檔