儲存空間(Bucket)內的檔案(Object)預設按照字母序排列。支援查看所有檔案、按目錄查看檔案、或調整每頁顯示數量。
列舉所有檔案
最常用的操作,擷取儲存空間中的所有檔案。
使用SDK
Java
更多用法請參見列舉檔案(Java 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.util.List;
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";
// 設定最大個數。
int maxKeys = 200;
// 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
String region = "cn-hangzhou";
// 建立OSSClient執行個體。
// 當OSSClient執行個體不再使用時,調用shutdown方法以釋放資源。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
String nextContinuationToken = null;
ListObjectsV2Result result = null;
// 分頁列舉,每次傳入上次返回結果中的nextContinuationToken。
do {
ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(bucketName).withMaxKeys(maxKeys);
listObjectsV2Request.setContinuationToken(nextContinuationToken);
result = ossClient.listObjectsV2(listObjectsV2Request);
List<OSSObjectSummary> sums = result.getObjectSummaries();
for (OSSObjectSummary s : sums) {
System.out.println("\t" + s.getKey());
}
nextContinuationToken = result.getNextContinuationToken();
} while (result.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();
}
}
}
}Python
更多用法見列舉檔案(Python SDK V2)。
import argparse
import alibabacloud_oss_v2 as oss
# 建立命令列參數解析器
parser = argparse.ArgumentParser(description="list objects v2 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() # 解析命令列參數
# 從環境變數中載入憑證資訊,用於身分識別驗證
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)
# 建立ListObjectsV2操作的分頁器
paginator = client.list_objects_v2_paginator()
# 遍曆對象列表的每一頁
for page in paginator.iter_page(oss.ListObjectsV2Request(
bucket=args.bucket
)
):
# 遍曆每一頁中的對象
for o in page.contents:
# 列印對象的名稱、大小和最後修改時間
print(f'Object: {o.key}, {o.size}, {o.last_modified}')
if __name__ == "__main__":
main() # 指令碼入口,當檔案被直接運行時調用main函數Go
更多用法見列舉檔案(Go SDK V2)。
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 // 儲存空間名稱
)
// init函數用於初始化命令列參數
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The `name` of the bucket.")
}
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")
}
// 載入預設配置並設定憑證提供者和地區
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
// 建立OSS用戶端
client := oss.NewClient(cfg)
// 建立列出對象的請求
request := &oss.ListObjectsV2Request{
Bucket: oss.Ptr(bucketName),
}
// 建立分頁器
p := client.NewListObjectsV2Paginator(request)
// 初始化頁碼計數器
var i int
log.Println("Objects:")
// 遍曆分頁器中的每一頁
for p.HasNext() {
i++
// 擷取下一頁的資料
page, err := p.NextPage(context.TODO())
if err != nil {
log.Fatalf("failed to get page %v, %v", i, err)
}
// 列印該頁中的每個對象的資訊
for _, obj := range page.Contents {
log.Printf("Object:%v, %v, %v\n", oss.ToString(obj.Key), obj.Size, oss.ToTime(obj.LastModified))
}
}
}
PHP
更多用法請參見列舉檔案(PHP SDK V2)。
<?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名稱(必填)
];
// 將參數描述轉換為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名稱
// 載入環境變數中的憑證資訊
// 使用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);
// 建立Paginator對象,用於分頁列出Bucket中的對象
// ListObjectsV2Paginator支援高效地分頁遍曆對象列表
$paginator = new Oss\Paginator\ListObjectsV2Paginator(client: $client);
$iter = $paginator->iterPage(new Oss\Models\ListObjectsV2Request(bucket: $bucket)); // 初始化分頁迭代器
// 遍曆對象分頁結果
foreach ($iter as $page) {
foreach ($page->contents ?? [] as $object) {
// 列印每個對象的關鍵資訊
// 輸出對象的Key、類型和大小
print("Object: $object->key, $object->type, $object->size\n");
}
}
C#
更多用法請參見列舉檔案(C# SDK V2)。
using OSS = AlibabaCloud.OSS.V2; // 為阿里雲OSS SDK建立別名,簡化後續使用
var region = "cn-hangzhou"; // 必須項,設定Bucket所在的地區(Region)。以華東1(杭州)為例,Region填寫為cn-hangzhou
var endpoint = null as string; // 可選項,指定訪問OSS服務的網域名稱。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com
var bucket = "your bucket name"; // 必須項,目標Bucket名稱
// 載入OSS SDK的預設配置,此配置會自動從環境變數中讀取憑證資訊(如AccessKey)
var cfg = OSS.Configuration.LoadDefault();
// 顯式設定使用環境變數擷取憑證,用於身分識別驗證(格式:OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET)
cfg.CredentialsProvider = new OSS.Credentials.EnvironmentVariableCredentialsProvider();
// 設定配置的Bucket地區
cfg.Region = region;
// 若已指定了endpoint,則覆蓋預設的endpoint
if(endpoint != null)
{
cfg.Endpoint = endpoint;
}
// 使用配置資訊建立OSS用戶端執行個體
using var client = new OSS.Client(cfg);
// 調用ListObjectsV2Paginator方法,擷取目標Bucket下所有對象。
var paginator = client.ListObjectsV2Paginator(new OSS.Models.ListObjectsV2Request()
{
Bucket = bucket
});
// 輸出儲存空間內的所有對象資訊
Console.WriteLine("Objects:");
await foreach (var page in paginator.IterPageAsync()) // 非同步遍曆每一頁結果
{
// 遍曆當前頁中的每個對象
foreach (var content in page.Contents ?? [])
{
// 輸出對象資訊:、大小(位元組)、最後修改時間
Console.WriteLine($"Object:{content.Key}, {content.Size}, {content.LastModified}");
}
}Node.js
更多用法請參見列舉檔案(Node.js)。
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 list () {
let continuationToken = null;
// 每頁列舉20個檔案。
const maxKeys = 20;
do {
const result = await client.listV2({
'continuation-token': continuationToken,
'max-keys': maxKeys
});
continuationToken = result.nextContinuationToken;
console.log(result);
}while(continuationToken)
}
list();Harmony
更多用法請參見列舉檔案。
import Client, { RequestError } from '@aliyun/oss';
// 建立OSS用戶端執行個體
const client = new Client({
// 請替換為RAM使用者的Access Key ID
accessKeyId: 'yourAccessKeyId',
// 請替換為RAM使用者的Access Key Secret
accessKeySecret: 'yourAccessKeySecret',
// 填寫Bucket所在的地區。例如,華東1(杭州)的Region為'oss-cn-hangzhou'
region: 'oss-cn-hangzhou',
});
/**
* 分頁列出Bucket中的對象。
* 使用listObjectsV2方法並結合continuationToken參數實現分頁列出對象。
*/
const listObjectsV2WithContinuationToken = async () => {
try {
let continuationToken: string | undefined; // 分頁標記,初始為空白
let isTruncated = true; // 是否還有更多個物件需要列出
// 迴圈列出對象,直到沒有更多個物件為止
while (isTruncated) {
const res = await client.listObjectsV2({
bucket: 'yourBucketName', // Bucket名稱,請替換為您實際使用的Bucket名稱
continuationToken, // 分頁標記,用於擷取下一頁資料
});
// 列印當前頁的對象及其元資訊
console.log(JSON.stringify(res));
// 更新分頁狀態
isTruncated = res.data.isTruncated; // 是否還有更多個物件
continuationToken = res.data.nextContinuationToken; // 下一頁的分頁標記
}
} catch (err) {
// 捕獲請求過程中的異常資訊
if (err instanceof RequestError) {
console.log('code: ', err.code); // 錯誤碼
console.log('message: ', err.message); // 錯誤訊息
console.log('requestId: ', err.requestId); // 請求ID
console.log('status: ', err.status); // HTTP狀態代碼
console.log('ec: ', err.ec); // 錯誤碼
} else {
console.log('unknown error: ', err);
}
}
};
// 調用listObjectsV2WithContinuationToken函數執行分頁列出對象的操作
listObjectsV2WithContinuationToken();
Swift
更多用法請參見列舉檔案。
import AlibabaCloudOSS
import Foundation
@main
struct Main {
static func main() async {
do {
// 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
let region = "cn-hangzhou"
// 填寫Bucket名稱。
let bucket = "yourBucketName"
// 可選項,指定訪問OSS服務的網域名稱。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com
let endpoint: String? = nil
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
let credentialsProvider = EnvironmentCredentialsProvider()
// 配置OSS用戶端參數
let config = Configuration.default()
.withRegion(region) // 設定Bucket所在地區
.withCredentialsProvider(credentialsProvider) // 設定訪問憑證
// 設定Endpoint
if let endpoint = endpoint {
config.withEndpoint(endpoint)
}
// 建立OSS用戶端執行個體
let client = Client(config)
// 建立分頁請求對象,用於遍曆儲存桶中的所有對象(分頁處理)
let paginator = client.listObjectsV2Paginator(
ListObjectsV2Request(
bucket: bucket // 指定要列出對象的Bucket名稱
)
)
// 遍曆分頁結果,逐頁擷取對象資訊
for try await page in paginator {
// 遍曆當前頁中的對象列表
for content in page.contents ?? [] {
// 輸出對象中繼資料:對象名稱、大小(位元組)、最後修改時間
print("Object key:\(content.key ?? ""), size: \(String(describing: content.size)), last modified: \(String(describing: content.lastModified))")
}
}
} catch {
// 錯誤輸出
print("error:\(error)")
}
}
}Ruby
更多用法請參見列舉檔案。
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')
# 列舉所有檔案。
objects = bucket.list_objects
objects.each { |o| puts o.key } Browser.js
更多用法請參見列舉檔案。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.18.0.min.js"></script>
</head>
<body>
<script>
const client = new OSS({
// yourRegion填寫Bucket所在地區。以華東1(杭州)為例,yourRegion填寫為oss-cn-hangzhou。
region: "yourRegion",
authorizationV4: true,
// 從STS服務擷取的臨時存取金鑰(AccessKey ID和AccessKey Secret)。
accessKeyId: 'yourAccessKeyId',
accessKeySecret: 'yourAccessKeySecret',
// 從STS服務擷取的安全性權杖(SecurityToken)。
stsToken: 'yourSecurityToken',
// 填寫Bucket名稱,例如examplebucket。
bucket: "examplebucket",
});
async function list(dir) {
try {
// 預設最多返回1000個檔案。
let result = await client.list();
console.log(result);
// 從上一次list操作讀取的最後一個檔案的下一個檔案開始繼續擷取檔案清單。
if (result.isTruncated) {
result = await client.list({ marker: result.nextMarker });
}
// 列出首碼為'ex'的檔案。
result = await client.list({
prefix: "ex",
});
console.log(result);
// 列出首碼為'ex'且檔案名稱字母序'example'之後的檔案。
result = await client.list({
prefix: "ex",
marker: "example",
});
console.log(result);
} catch (e) {
console.log(e);
}
}
list();
</script>
</body>
</html>
Android
更多用法請參見列舉檔案。
private String marker = null;
private boolean isCompleted = false;
// 分頁列舉所有object。
public void getAllObject() {
do {
OSSAsyncTask task = getObjectList();
// 阻塞等待請求完成擷取NextMarker,請求下一頁時需要將請求的marker設定為上一頁請求返回的NextMarker。第一頁無需設定。
// 樣本中通過迴圈分頁列舉資料,因此需要阻塞等待請求完成擷取NextMarker才能請求下一頁資料,實際使用時可根據實際情境判斷是否需要阻塞。
task.waitUntilFinished();
} while (!isCompleted);
}
// 列舉一頁檔案。
public OSSAsyncTask getObjectList() {
// 填寫Bucket名稱。
ListObjectsRequest request = new ListObjectsRequest("examplebucket");
// 填寫每頁返迴文件的最大個數。如果不設定此參數,則預設值為100,maxkeys的取值不能大於1000。
request.setMaxKeys(20);
request.setMarker(marker);
OSSAsyncTask task = oss.asyncListObjects(request, new OSSCompletedCallback<ListObjectsRequest, ListObjectsResult>() {
@Override
public void onSuccess(ListObjectsRequest request, ListObjectsResult result) {
for (OSSObjectSummary objectSummary : result.getObjectSummaries()) {
Log.i("ListObjects", objectSummary.getKey());
}
// 最後一頁。
if (!result.isTruncated()) {
isCompleted = true;
return;
}
// 下一次列舉檔案的marker。
marker = result.getNextMarker();
}
@Override
public void onFailure(ListObjectsRequest request, ClientException clientException, ServiceException serviceException) {
isCompleted = true;
// 請求異常。
if (clientException != null) {
// 用戶端異常,例如網路異常等。
clientException.printStackTrace();
}
if (serviceException != null) {
// 服務端異常。
Log.e("ErrorCode", serviceException.getErrorCode());
Log.e("RequestId", serviceException.getRequestId());
Log.e("HostId", serviceException.getHostId());
Log.e("RawMessage", serviceException.getRawMessage());
}
}
});
return task;
}C++
更多用法請參見列舉檔案。
#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";
/* 初始化網路等資源。*/
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::string nextMarker = "";
bool isTruncated = false;
do {
/* 列舉檔案。*/
ListObjectsRequest request(BucketName);
request.setMarker(nextMarker);
auto outcome = client.ListObjects(request);
if (!outcome.isSuccess()) {
/* 異常處理。*/
std::cout << "ListObjects fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
ShutdownSdk();
return -1;
}
else {
for (const auto& object : outcome.result().ObjectSummarys()) {
std::cout << "object"<<
",name:" << object.Key() <<
",size:" << object.Size() <<
",lastmodify time:" << object.LastModified() << std::endl;
}
}
nextMarker = outcome.result().NextMarker();
isTruncated = outcome.result().IsTruncated();
} while (isTruncated);
/* 釋放網路等資源。*/
ShutdownSdk();
return 0;
}iOS
更多用法請參見列舉檔案。
do {
OSSGetBucketRequest *getBucket = [OSSGetBucketRequest new];
getBucket.bucketName = @"examplebucket";
getBucket.marker = _marker; // Accessing the _marker instance variable
getBucket.maxKeys = 20;
OSSTask *getBucketTask = [client getBucket:getBucket];
[getBucketTask continueWithBlock:^id(OSSTask *task) {
if (!task.error) {
OSSGetBucketResult *result = task.result;
NSLog(@"Get bucket success!");
NSLog(@"objects: %@", result.contents);
if (result.isTruncated) {
_marker = result.nextMarker; // Update the _marker instance variable
_isCompleted = NO;
} else {
_isCompleted = YES;
}
} else {
_isCompleted = YES;
NSLog(@"Get bucket failed, error: %@", task.error);
}
return nil;
}];
// 實現同步阻塞等待任務完成。
[getBucketTask waitUntilFinished];
} while (!_isCompleted);C
更多用法請參見列舉檔案。
#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";
/* yourRegion填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。*/
const char *region = "yourRegion";
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"));
//需要額外配置以下兩個參數
aos_str_set(&options->config->region, region);
options->config->signature_version = 4;
/* 是否設定了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、access_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_status_t *resp_status = NULL;
oss_list_object_params_t *params = NULL;
oss_list_object_content_t *content = NULL;
int size = 0;
char *line = NULL;
char *prefix = "";
char *nextMarker = "";
aos_str_set(&bucket, bucket_name);
params = oss_create_list_object_params(pool);
/* 通過max_ret參數設定需要返回的檔案數量。*/
/* 預設列舉檔案數量最多為1000個。如果列舉的檔案數量超出1000,則只返回按字母排序的前1000個檔案,且返回結果中的truncated為true,並返回next_marker作為下次讀取的起點。*/
params->max_ret = 100;
aos_str_set(¶ms->prefix, prefix);
aos_str_set(¶ms->marker, nextMarker);
printf("Object\tSize\tLastModified\n");
/* 列舉所有檔案。*/
do {
resp_status = oss_list_object(oss_client_options, &bucket, params, NULL);
if (!aos_status_is_ok(resp_status))
{
printf("list object failed\n");
break;
}
aos_list_for_each_entry(oss_list_object_content_t, content, ¶ms->object_list, node) {
++size;
line = apr_psprintf(pool, "%.*s\t%.*s\t%.*s\n", content->key.len, content->key.data,
content->size.len, content->size.data,
content->last_modified.len, content->last_modified.data);
printf("%s", line);
}
nextMarker = apr_psprintf(pool, "%.*s", params->next_marker.len, params->next_marker.data);
aos_str_set(¶ms->marker, nextMarker);
aos_list_init(¶ms->object_list);
aos_list_init(¶ms->common_prefix_list);
} while (params->truncated == AOS_TRUE);
printf("Total %d\n", size);
/* 釋放記憶體池,相當於釋放了請求過程中各資源分派的記憶體。*/
aos_pool_destroy(pool);
/* 釋放之前分配的全域資源。*/
aos_http_io_deinitialize();
return 0;
}使用ossutil
以下樣本展示了如何列舉儲存空間examplebucket中所有Object的資訊。
ossutil api list-objects-v2 --bucket examplebucket使用OSS控制台
登入OSS管理主控台。
在左側導覽列,單擊Bucket 列表。
進入目標Bucket,單擊檔案管理 > 檔案清單。
當前頁面將分頁顯示Bucket內的所有Object,預設每頁顯示50個Object,最多可顯示500個。
列舉指定目錄下所有檔案
如果需要擷取一個目錄下(包含其所有子目錄)的全部檔案,形成一個扁平化的完整列表,只需設定 prefix參數即可。
prefix的作用是按首碼篩選,它會返回所有檔案名稱(Key)以此字串開頭的對象。由於OSS採用的是扁平儲存結構(沒有物理檔案夾),這個簡單的篩選就能有效地擷取邏輯目錄下的所有內容。
使用SDK
Java
完整程式碼範例請參見列舉檔案(Java SDK)。
// ...
// 關鍵代碼:設定首碼
ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(bucketName);
listObjectsV2Request.setPrefix("images/"); // 指定首碼
ListObjectsV2Result result = ossClient.listObjectsV2(listObjectsV2Request);
// ...Python
完整程式碼範例請參見列舉檔案(Python SDK V2)。
# ...
# 關鍵代碼:添加prefix參數
for page in paginator.iter_page(oss.ListObjectsV2Request(
bucket='your-bucket',
prefix='images/' # 指定首碼
)):
# ...Go
完整程式碼範例請參見列舉檔案(Go SDK V2)。
// ...
// 關鍵代碼:設定首碼
request := &oss.ListObjectsV2Request{
Bucket: oss.Ptr(bucketName),
Prefix: oss.Ptr("images/"), // 列舉指定首碼的所有對象
}
// ...Node.js
完整程式碼範例請參見列舉檔案(Node.js)。
// ...
// 關鍵代碼:設定首碼
const result = await client.listV2({
prefix: 'images/' // 指定首碼
});
// ...Harmony
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定首碼
const res = await client.listObjectsV2({
bucket: 'yourBucketName',
prefix: 'images/', // 指定首碼
});
// ...Ruby
完整程式碼範例請參見列舉檔案。
# ...
# 關鍵代碼:設定首碼
objects = bucket.list_objects(:prefix => 'images/') # 指定首碼
# ...Android
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定首碼
ListObjectsRequest request = new ListObjectsRequest("examplebucket");
request.setPrefix("images/"); // 指定首碼
// ...C++
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定首碼
ListObjectsRequest request(BucketName);
request.setPrefix("images/"); // 指定首碼
// ...iOS
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定首碼
getBucket.prefix = @"images/"; // 指定首碼
// ...C
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定首碼
char *prefix = "images/"; // 指定首碼
aos_str_set(¶ms->prefix, prefix);
// ...使用ossutil
以下樣本展示了如何列舉儲存空間examplebucket中指定首碼dir下的所有Object的資訊。
ossutil api list-objects-v2 --bucket examplebucket --prefix dir/輸出結果樣本
假設Bucket中有以下檔案:
images/cat.jpg
images/dog.png
images/archive/old.zip
readme.txt當請求設定為 prefix="images/" 時,會返回:
images/
images/archive/
images/archive/old.zip
images/cat.jpg
images/dog.png列舉指定目錄下的直屬檔案和子目錄
在 prefix 的基礎上,增加 delimiter 參數(通常設為 /)。這會將返回結果分為 檔案(objects) 和 子目錄(commonPrefixes) 兩部分。
delimiter的作用是按層級分組。當它存在時,OSS會對prefix篩選後的結果進行二次處理:
如果檔案名稱在
prefix之後不再包含/,則被視為檔案。如果檔案名稱在
prefix之後還包含/,則從開頭到第一個/的部分會被視為一個子目錄。
使用SDK
Java
完整程式碼範例請參見列舉檔案(Java SDK)。
// ...
// 關鍵代碼:設定分隔字元
ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(bucketName);
listObjectsV2Request.setPrefix("images/"); // 指定目錄
listObjectsV2Request.setDelimiter("/"); // 設定分隔字元
ListObjectsV2Result result = ossClient.listObjectsV2(listObjectsV2Request);
// 遍曆目前的目錄下的檔案
for (OSSObjectSummary objectSummary : result.getObjectSummaries()) {
System.out.println("檔案: " + objectSummary.getKey());
}
// 遍曆子目錄
for (String commonPrefix : result.getCommonPrefixes()) {
System.out.println("子目錄: " + commonPrefix);
}
// ...Python
完整程式碼範例請參見列舉檔案(Python SDK V2)。
# ...
# 關鍵代碼:添加delimiter參數
for page in paginator.iter_page(oss.ListObjectsV2Request(
bucket=args.bucket,
prefix="images/", # 指定目錄
delimiter="/", # 設定分隔字元
)):
# 遍曆目前的目錄下的檔案
for file in page.contents:
print(f'檔案: {file.key}')
# 遍曆子目錄
for prefix in page.common_prefixes:
print(f'子目錄: {prefix.prefix}')
# ...Go
// ...
// 關鍵代碼:設定分隔字元
request := &oss.ListObjectsV2Request{
Bucket: oss.Ptr(bucketName),
Prefix: oss.Ptr("images/"), // 指定目錄
Delimiter: oss.Ptr("/"), // 設定分隔字元
}
// 遍曆目前的目錄下的檔案
for _, obj := range lsRes.Contents {
log.Printf("檔案: %v\n", oss.ToString(obj.Key))
}
// 遍曆子目錄
for _, prefix := range lsRes.CommonPrefixes {
log.Printf("子目錄: %v\n", *prefix.Prefix)
}
// ...PHP
完整程式碼範例請參見列舉檔案(PHP SDK V2)。
// ...
// 關鍵代碼:建立分頁器,並設定 delimiter 以區分檔案和子目錄
$paginator = new Oss\Paginator\ListObjectsV2Paginator(client: $client);
$iter = $paginator->iterPage(new Oss\Models\ListObjectsV2Request(
bucket: $bucket,
prefix: "",
delimiter: "/"
));
// 遍曆分頁結果
foreach ($iter as $page) {
// 遍曆 contents 擷取目前的目錄下的檔案
foreach ($page->contents ?? [] as $object) {
echo "檔案: " . $object->key . PHP_EOL;
}
// 遍曆 commonPrefixes 擷取子目錄
foreach ($page->commonPrefixes ?? [] as $prefixObject) {
echo "子目錄: " . $prefixObject->prefix . PHP_EOL;
}
}
// ...Node.js
完整程式碼範例請參見列舉檔案(Node.js)。
// ...
// 關鍵代碼:設定分隔字元
const result = await client.listV2({
prefix: dir, // 指定目錄
delimiter: '/' // 設定分隔字元
});
// 遍曆目前的目錄下的檔案
if (result && result.objects) {
result.objects.forEach(obj => {
console.log('檔案: %s', obj.name);
});
}
// 遍曆子目錄
if (result && result.prefixes) {
result.prefixes.forEach(subDir => {
console.log('子目錄: %s', subDir);
});
}
// ...Harmony
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定分隔字元
const res = await client.listObjectsV2({
bucket: 'yourBucketName', // Bucket名稱
prefix: 'images/', // 指定目錄
delimiter: '/', // 設定分隔字元
});
// 遍曆目前的目錄下的檔案
if (res && res.objects) {
res.objects.forEach(obj => {
console.log('檔案:', obj.name);
});
}
// 遍曆子目錄
if (res && res.prefixes) {
res.prefixes.forEach(subDir => {
console.log('子目錄:', subDir);
});
}
// ...Browser.js
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定分隔字元
let result = await client.list({
prefix: 'images/', // 指定目錄
delimiter: "/", // 設定分隔字元
});
// 遍曆目前的目錄下的檔案
result.objects.forEach(function (obj) {
console.log("檔案: %s", obj.name);
});
// 遍曆子目錄
result.prefixes.forEach(function (subDir) {
console.log("子目錄: %s", subDir);
});
// ...Ruby
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定分隔字元
objects = bucket.list_objects(prefix: 'images/', delimiter: '/')
// 遍曆目前的目錄下的檔案
if obj.is_a?(Aliyun::OSS::Object)
puts "檔案: #{obj.key}"
end
// 遍曆子目錄
if obj.is_a?(String) # Common Prefix
puts "子目錄: #{obj}"
end
// ...C++
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定分隔字元
ListObjectsRequest request(BucketName);
request.setPrefix("images/"); // 指定目錄
request.setDelimiter("/"); // 設定分隔字元
// 遍曆目前的目錄下的檔案
for (const auto& object : outcome.result().ObjectSummarys()) {
std::cout << "檔案:" << object.Key() << std::endl;
}
// 遍曆子目錄
for (const auto& commonPrefix : outcome.result().CommonPrefixes()) {
std::cout << "子目錄:" << commonPrefix << std::endl;
}
// ...C
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定分隔字元
params = oss_create_list_object_params(pool);
aos_str_set(¶ms->prefix, "images/"); // 指定目錄
aos_str_set(¶ms->delimiter, "/"); // 設定分隔字元
// 遍曆目前的目錄下的檔案
aos_list_for_each_entry(oss_list_object_content_t, content, ¶ms->object_list, node) {
printf("檔案: %.*s\n", content->key.len, content->key.data);
}
// 遍曆子目錄
aos_list_for_each_entry(oss_list_object_common_prefix_t, commonPrefix, ¶ms->common_prefix_list, node) {
printf("子目錄: %.*s\n", commonPrefix->prefix.len, commonPrefix->prefix.data);
}
// ...使用ossutil
以下樣本展示了如何列舉儲存空間examplebucket中目前的目錄下的Object的資訊。
ossutil api list-objects-v2 --bucket examplebucket --prefix images/ --delimiter /輸出結果樣本
當請求同時設定為prefix="images/"和 delimiter="/" 時,結果會被分組:
檔案:
images/
images/cat.jpg
images/dog.png
目錄:
images/archive/列舉指定位置後的檔案
使用 startAfter 參數(部分舊版SDK使用 marker),可以跳過所有按字母序排在該檔案名稱之前的檔案。
使用SDK
Java
完整程式碼範例請參見列舉檔案(Java SDK)。
// ...
// 關鍵代碼:設定起始位置
ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(bucketName);
listObjectsV2Request.setStartAfter("images/cat.jpg"); // 從指定檔案後開始
ListObjectsV2Result result = ossClient.listObjectsV2(listObjectsV2Request);
// ...Python
完整程式碼範例請參見列舉檔案(Python SDK V2)。
# ...
# 關鍵代碼:添加start_after參數
for page in paginator.iter_page(oss.ListObjectsV2Request(
bucket=args.bucket,
start_after="images/cat.jpg", # 從指定檔案後開始
)):
# ...Go
完整程式碼範例請參見列舉檔案(Go SDK V2)。
// ...
// 關鍵代碼:設定起始位置
request := &oss.ListObjectsV2Request{
Bucket: oss.Ptr(bucketName),
StartAfter: oss.Ptr("images/cat.jpg"), // 從指定檔案後開始
}
// ...PHP
完整程式碼範例請參見列舉檔案(PHP SDK V2)。
// ...
// 關鍵代碼:設定起始位置
$paginator = new Oss\Paginator\ListObjectsV2Paginator(client: $client);
$iter = $paginator->iterPage(new Oss\Models\ListObjectsV2Request(
bucket: $bucket,
startAfter:"images/cat.jpg", // 指定列舉對象的起始位置
));
// ...Ruby
完整程式碼範例請參見列舉檔案。
# ...
# 關鍵代碼:設定marker(起始位置)
objects = bucket.list_objects(:marker => 'images/cat.jpg') # 從指定檔案後開始
# ...Android
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定marker(起始位置)
ListObjectsRequest request = new ListObjectsRequest("examplebucket");
request.setMarker("images/cat.jpg"); // 從指定檔案後開始
// ...C++
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定marker(起始位置)
ListObjectsRequest request(BucketName);
request.setMarker("images/cat.jpg"); // 從指定檔案後開始
// ...iOS
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定marker(起始位置)
getBucket.marker = @"images/cat.jpg"; // 從指定檔案後開始
// ...C
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:設定marker(起始位置)
char *nextMarker = "images/cat.jpg"; // 從指定檔案後開始
aos_str_set(¶ms->marker, nextMarker);
// ...使用ossutil
以下樣本展示了如何列舉儲存空間examplebucket中指從test.txt之後的Object的資訊。
ossutil api list-objects-v2 --bucket examplebucket --start-after test.txt輸出結果樣本:
假設Bucket中有:
images/cat.jpg
images/dog.png
images/archive/old.zip
readme.txt當請求設定為 start_after="images/cat.jpg" 時,輸出結果將不包含"images/cat.jpg"及按字母序排在它之前的所有檔案:
images/dog.png
readme.txt調整每頁檔案數量
MaxKey參數控制單次請求返回的檔案數量。預設值為100,最大值為1000。
使用SDK
Java
完整程式碼範例請參見列舉檔案(Java SDK)。
// ...
// 關鍵代碼:添加max_keys參數設定每頁檔案數量
ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(bucketName);
listObjectsV2Request.setMaxKeys(1000); // 每頁最多1000個檔案
ListObjectsV2Result result = ossClient.listObjectsV2(listObjectsV2Request);
// ...Python
完整程式碼範例請參見列舉檔案(Python SDK V2)。
# ...
# 關鍵代碼:添加max_keys參數設定每頁檔案數量
for page in paginator.iter_page(oss.ListObjectsV2Request(
bucket=args.bucket,
max_keys=1000, # 每頁最多1000個檔案
)):
# ...Go
完整程式碼範例請參見列舉檔案(Go SDK V2)。
// ...
// 關鍵代碼:添加max_keys參數設定每頁檔案數量
request := &oss.ListObjectsV2Request{
Bucket: oss.Ptr(bucketName),
MaxKeys: 1000, // 每頁最多1000個檔案
}
// ...PHP
完整程式碼範例請參見列舉檔案(PHP SDK V2)。
// ...
// 關鍵代碼:建立分頁器,並通過 maxKeys 參數設定每頁返回的最大檔案數量
$paginator = new Oss\Paginator\ListObjectsV2Paginator(client: $client);
$iter = $paginator->iterPage(new Oss\Models\ListObjectsV2Request(
bucket: $bucket,
maxKeys: 10, //每次列舉返回的最大對象數量
));
// ...Node.js
完整程式碼範例請參見列舉檔案(Node.js)。
// ...
// 關鍵代碼:添加max_keys參數設定每頁檔案數量
const result = await client.listV2({
"max-keys": 1000 // 每頁最多1000個檔案
});
// ...Android
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:添加max_keys參數設定每頁檔案數量
ListObjectsRequest request = new ListObjectsRequest("examplebucket");
request.setMaxKeys(1000); // 每頁最多1000個檔案
// ...C++
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:添加max_keys參數設定每頁檔案數量
ListObjectsRequest request(BucketName);
request.setMaxKeys(1000); // 每頁最多1000個檔案
// ...iOS
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:添加max_keys參數設定每頁檔案數量
getBucket.maxKeys = 1000; // 每頁最多1000個檔案
// ...C
完整程式碼範例請參見列舉檔案。
// ...
// 關鍵代碼:添加max_keys參數設定每頁檔案數量
params->max_ret = 1000; // 每頁最多1000個檔案
// ...使用ossutil
以下樣本展示了如何列舉儲存空間examplebucket中指定首碼dir下,前100個Object的資訊。
ossutil api list-objects-v2 --bucket examplebucket --prefix dir/ --max-keys 100輸出結果樣本:
假設Bucket中有:
images/cat.jpg
images/dog.png
images/archive/old.zip
readme.txt若
maxKeys設定為2,所有檔案將以每頁2個的形式分頁返回。
若
maxKeys設定為100,所有檔案將以每頁100個的形式分頁返回。
應用於生產
效能最佳化
調大分頁大小:將
MaxKey設為1000,在網路條件良好時能顯著減少API調用次數。但要注意記憶體使用量,避免一次性載入過多資料。並行分區處理:如果檔案數量達到幾十萬甚至更多,單純按順序列舉會很慢。這時可以按目錄分別處理,比如同時處理images/、documents/、logs/等不同目錄,能提升列舉速度。
緩衝目錄結構:對於不常變化的目錄結構,可以緩衝列舉結果,減少重複調用。
成本控制
配額與限制
單次返回上限:最多返回1000個檔案。
排序方式:僅支援按檔案名稱字母序排序
常見問題
OSS是否支援列舉指定頁數的檔案?
不支援。
如何列舉指定目錄下所有檔案?
您可以使用命令列工具ossutil2.0的命令list-objects-v2(get-bucket-v2)列舉指定目錄下的所有檔案資訊,包括檔案目錄結構和檔案名稱等。
列舉檔案時是否支援按檔案最後一次修改時間進行排序?
不支援。如果您需要按照檔案最後一次修改時間進行排序,建議使用資料索引功能。