存储空间(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)列举指定目录下的所有文件信息,包括文件目录结构和文件名称等。
列举文件时是否支持按文件最后一次修改时间进行排序?
不支持。如果您需要按照文件最后一次修改时间进行排序,建议使用数据索引功能。