本文介绍如何在开启版本控制状态下列举存储空间下(Bucket)的所有文件(Object)、指定个数的文件、指定前缀的文件等。

列举Bucket中所有Object的信息

以下代码用于列举指定Bucket中包括删除标记(Delete Marker)在内的所有Object的版本信息。

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "httpss://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
String bucketName = "<yourBucketName>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 列举包括删除标记在内的所有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());

// 关闭OSSClient。
ossClient.shutdown();

列举指定前缀Object的版本信息

以下代码用于列举指定前缀Object的版本信息:

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
String bucketName = "<yourBucketName>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 指定列举以"test-"为前缀的Object的版本信息。
String prefix = "test-";
String nextKeyMarker = null;
String nextVersionMarker = null;
VersionListing versionListing = null;
do {
    ListVersionsRequest listVersionsRequest = new ListVersionsRequest()
            .withBucketName(bucketName)
            .withKeyMarker(nextKeyMarker)
            .withVersionIdMarker(nextVersionMarker)
            .withEncodingType(OSSConstants.URL_ENCODING)
            .withPrefix(prefix);

    versionListing = ossClient.listVersions(listVersionsRequest);
    // 查看Object的版本信息。
    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());

// 关闭OSSClient。
ossClient.shutdown();

列举指定个数Object的版本信息

以下代码用于列举指定个数Object的版本信息:

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
String bucketName = "<yourBucketName>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 指定最多返回200个结果。
ListVersionsRequest listVersionsRequest = new ListVersionsRequest()
            .withBucketName(bucketName)
            .withMaxResults(200);

versionListing = ossClient.listVersions(listVersionsRequest);
for (OSSVersionSummary ossVersion : versionListing.getVersionSummaries()) {
    System.out.println("key name: " + ossVersion.getKey());
    // 在未开启版本控制的情况下,VersionId为none。
    System.out.println("versionid: " + ossVersion.getVersionId());
    System.out.println("Is latest: " + ossVersion.isLatest());
    System.out.println("Is delete marker: " + ossVersion.isDeleteMarker());
}

// 关闭OSSClient。
ossClient.shutdown();

分页列举所有Object的版本信息

以下代码用于分页列举所有Object的版本信息:

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
String bucketName = "<yourBucketName>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 分页列举所有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());

// 关闭OSSClient。
ossClient.shutdown();

列举名称中包含特殊字符的Object

如果文件名称含有以下特殊字符,需要进行编码传输。OSS目前仅支持URL编码。

  • 单引号(' ')
  • 双引号(" ")
  • and符号(&)
  • 尖括号(< >)
  • 顿号(、)
  • 中文

以下代码用于列举名称中包含特殊字符的Object:

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
String bucketName = "<yourBucketName>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 指定返回结果以URL编码进行传输。
String nextKeyMarker = null;
String nextVersionMarker = null;
VersionListing versionListing = null;
do {
    ListVersionsRequest listVersionsRequest = new ListVersionsRequest()
            .withBucketName(bucketName)
            .withKeyMarker(nextKeyMarker)
            .withVersionIdMarker(nextVersionMarker)
            .withEncodingType(OSSConstants.URL_ENCODING)

    versionListing = ossClient.listVersions(listVersionsRequest);
      // 查看Object的版本信息。
    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());

// 关闭OSSClient。
ossClient.shutdown();

文件夹功能

OSS没有文件夹的概念,所有元素都是以文件来存储。创建文件夹本质上来说是创建了一个大小为0并以正斜线(/)结尾的文件。这个文件可以被上传和下载,控制台会对以正斜线(/)结尾的文件以文件夹的方式展示。

通过delimiter和prefix两个参数可以模拟文件夹功能:

  • 如果设置prefix为某个文件夹名称,则会列举以此prefix开头的文件,即该文件夹下所有的文件和子文件夹(目录)均显示为Object。
  • 如果在设置了prefix的情况下,将delimiter设置为正斜线(/),则只列举该文件夹下的文件和子文件夹(目录),该文件夹下的子文件夹(目录)显示为CommonPrefixes,子文件夹下的文件和文件夹不显示。

假设存储空间中包含oss.jpgfun/test.jpgfun/movie/001.avifun/movie/007.avi4个文件,正斜线(/)作为文件夹的分隔符。以下示例说明了如何通过模拟文件夹的方式列举文件。

  • 列举根目录下的Object的版本信息

    以下代码用于列举根目录下的Object的版本信息:

    // Endpoint以杭州为例,其它Region请按实际情况填写。
    String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    String accessKeyId = "<yourAccessKeyId>";
    String accessKeySecret = "<yourAccessKeySecret>";
    String bucketName = "<yourBucketName>";
    
    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // 指定delimiter参数为正斜线(/),将会列举根目录下的Object的版本信息以及文件夹名称。
    String delimiter = "/";
    String nextKeyMarker = null;
    String nextVersionMarker = null;
    VersionListing versionListing = null;
    do {
        ListVersionsRequest listVersionsRequest = new ListVersionsRequest()
                .withBucketName(bucketName)
                .withKeyMarker(nextKeyMarker)
                .withVersionIdMarker(nextVersionMarker)
                .withEncodingType(OSSConstants.URL_ENCODING)
                .withDelimiter(delimiter);
    
        versionListing = ossClient.listVersions(listVersionsRequest);
        // 查看Object的版本信息。
        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());
        }
        // 查看根目录下以正斜线(/)结尾的文件夹名称。
        for (String commonPrefix : versionListing.getCommonPrefixes()) {
            System.out.println("commonPrefix: " + commonPrefix);
        }
    
        nextKeyMarker = versionListing.getNextKeyMarker();
        nextVersionMarker = versionListing.getNextVersionIdMarker();
    } while (versionListing.isTruncated());
    
    // 关闭OSSClient。
    ossClient.shutdown();

    返回结果

    key name: oss.jpg
    versionid: CAEQEhiBgMCw8Y7FqBciIGIzMDE3MTEzOWRiMDRmZmFhMmRlMjljZWI0MWU4****
    Is latest: true
    Is delete marker: false
    
    commonPrefix: fun/
  • 列举目录下的文件和子目录

    以下代码用于列举指定目录下的文件和子目录:

    // Endpoint以杭州为例,其它Region请按实际情况填写。
    String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    String accessKeyId = "<yourAccessKeyId>";
    String accessKeySecret = "<yourAccessKeySecret>";
    String bucketName = "<yourBucketName>";
    
    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // 设置prefix参数来获取fun目录下的所有文件与文件夹,同时设置delimiter参数为正斜线(/)作为文件夹的分隔符。
    String prefix = "fun/";
    String delimiter = "/";
    String nextKeyMarker = null;
    String nextVersionMarker = null;
    VersionListing versionListing = null;
    do {
        ListVersionsRequest listVersionsRequest = new ListVersionsRequest()
                .withBucketName(bucketName)
                .withKeyMarker(nextKeyMarker)
                .withVersionIdMarker(nextVersionMarker)
                .withEncodingType(OSSConstants.URL_ENCODING)
                .withDelimiter(delimiter)
                .withPrefix(prefix);
    
        versionListing = ossClient.listVersions(listVersionsRequest);
        // 查看Object的版本信息。
        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());
        }
        // 查看fun目录下的子目录名称。
        for (String commonPrefix : versionListing.getCommonPrefixes()) {
            System.out.println("commonPrefix: " + commonPrefix);
        }
    
        nextKeyMarker = versionListing.getNextKeyMarker();
        nextVersionMarker = versionListing.getNextVersionIdMarker();
    } while (versionListing.isTruncated());
    
    // 关闭OSSClient。
    ossClient.shutdown();

    返回结果:

    key name: fun/test.jpg
    versionid: CAEQEhiBgIC48Y7FqBciIDU4NjAzMjczMTY5NDRjYmVhNGY4NTM2YTdjY2Ji****
    Is latest: true
    Is delete marker: false
    
    commonPrefix: fun/movie/