Skip to content
大纲

列举存储空间中的文件

FOS SDK支持用户通过以下两种方式列举出object:

  • 简单列举
  • 通过参数复杂列举

除此之外,用户还可在列出文件的同时模拟文件夹

简单列举

当用户希望简单快速列举出所需的文件时,可通过listObjects方法返回ListObjectsResponse对象,ListObjectsResponse对象包含了此次listObject请求的返回结果。用户可以通过ListObjectsResponse中的getContents方法获取所有Object的描述信息。

java
public void listObjects(FosClient client, String bucketName) {
    // 获取指定Bucket下的所有Object信息
    ListObjectsResponse listing = client.listObjects(bucketName);
    // 遍历所有Object
    for (FosObjectSummary objectSummary : listing.getContents()) {
        System.out.println("ObjectKey: " + objectSummary.getKey());
    }
}

注意:

  1. 默认情况下,如果Bucket中的Object数量大于1000,则只会返回1000个Object,并且返回结果中IsTruncated值为True,并返回NextMarker做为下次读取的起点。
  2. 若想增大返回Object的数目,可以使用Marker参数分次读取。

通过参数复杂列举

除上述简单列举外,用户还可通过设置ListObjectsRequest的参数实现各种灵活的查询功能。ListObjectsRequest的可设置的参数如下:

参数功能使用方式
Prefix限定返回的object key必须以prefix作为前缀setPrefix(String prefix)
Delimiter是一个用于对Object名字进行分组的字符所有名字包含指定的前缀且第一次出现。Delimiter字符之间的Object作为一组元素: CommonPrefixessetDelimiter(String delimiter)
Marker设定结果从marker之后按字母排序的第一个开始返回setMarker(String marker)
MaxKeys限定此次返回object的最大数,最大为1000,默认值是1000。如果指定的值大于1000,按1000操作setMaxKeys(int maxKeys)

注意:

  1. 如果有Object以Prefix命名,当仅使用Prefix查询时,返回的所有Key中仍会包含以Prefix命名的Object。
  2. 如果有Object以Prefix命名,当使用Prefix和Delimiter组合查询时,返回的所有Key中会有Null,Key的名字不包含Prefix前缀。

下面我们分别以几个案例说明通过参数列举的方法: 指定最大返回条数

java
// 指定最大返回条数为500
ListObjectsRequest listObjectsRequest = new ListObjectsRequest("bucketName");
listObjectsRequest.withMaxKeys(500);
ListObjectsResponse listObjectsResponse = client.listObjects(listObjectsRequest);
for(FosObjectSummary objectSummary :listObjectsResponse.getContents()) {
    System.out.println("ObjectKey:" + objectSummary.getKey());
}

返回指定前缀的object

java
// 指定返回前缀为test的object
ListObjectsRequest listObjectsRequest = new ListObjectsRequest("bucketName");
listObjectsRequest.withPrefix("test");
ListObjectsResponse listObjectsResponse = client.listObjects(listObjectsRequest);
for(FosObjectSummary objectSummary :listObjectsResponse.getContents()) {
    System.out.println("ObjectKey:" + objectSummary.getKey());
}

从指定Object后返回

java
// 用户可以定义不包括某object,从其之后开始返回
ListObjectsRequest listObjectsRequest = new ListObjectsRequest("bucketName");
listObjectsRequest.withMarker("object");
ListObjectsResponse listObjectsResponse = client.listObjects(listObjectsRequest);
for(FosObjectSummary objectSummary :listObjectsResponse.getContents()) {
    System.out.println("ObjectKey:" + objectSummary.getKey());
}

分页获取所有Object

java
// 用户可设置每页最多500条记录
ListObjectsRequest listObjectsRequest = new ListObjectsRequest("bucketName");
listObjectsRequest.withMaxKeys(500);
ListObjectsResponse listObjectsResponse;boolean isTruncated = true;
while (isTruncated) {
    listObjectsResponse = client.listObjects(listObjectsRequest);
    isTruncated = listObjectsResponse.isTruncated();
    if (listObjectsResponse.getNextMarker() != null) {
        listObjectsRequest.withMarker(listObjectsResponse.getNextMarker());
    }
}

分页获取所有特定Object后的结果

java
// 用户可设置每页最多500条记录,并从某特定object之后开始获取
ListObjectsRequest listObjectsRequest = new ListObjectsRequest("bucketName");
listObjectsRequest.withMaxKeys(500);
listObjectsRequest.withMarker("object");
ListObjectsResponse listObjectsResponse;
boolean isTruncated = true;
while (isTruncated) {
    listObjectsResponse = client.listObjects(listObjectsRequest);
    isTruncated = listObjectsResponse.isTruncated();
    if (listObjectsResponse.getNextMarker() != null) {
        listObjectsRequest.withMarker(listObjectsResponse.getNextMarker());
    }
}

分页获取所有指定前缀的Object结果

java
// 用户可设置分页获取指定前缀的Object,每页最多500条记录
ListObjectsRequest listObjectsRequest = new ListObjectsRequest("bucketName");
listObjectsRequest.withMaxKeys(500);
listObjectsRequest.withPrefix("object");
ListObjectsResponse listObjectsResponse;
boolean isTruncated = true;
while (isTruncated) {
    listObjectsResponse = client.listObjects(listObjectsRequest);
    isTruncated = listObjectsResponse.isTruncated();
    if (listObjectsResponse.getNextMarker() != null) {
        listObjectsRequest.withMarker(listObjectsResponse.getNextMarker());
    }
}

listObject方法返回的解析类中可供调用的参数有:

参数说明
nameBucket名称
prefix匹配以prefix开始到第一次出现Delimiter字符之间的object作为一组元素返回
marker本次查询的起点
maxKeys请求返回的最大数目
isTruncated指明是否所有查询都返回了;false-本次已经返回所有结果,true-本次还没有返回所有结果
contents返回的一个Object的容器
+keyObject名称
+lastModified此Object最后一次被修改的时间
+eTagObject的HTTP协议实体便签
+storageClassObject的存储形态
+sizeObject的内容的大小(字节数)
+ownerObject对应Bucket所属用户信息
++idBucket Owner的用户ID
++displayNameBucket Owner的名称

模拟文件夹功能

在FOS的存储结果中是没有文件夹这个概念的,所有元素都是以Object来存储,但FOS的用户在使用数据时往往需要以文件夹来管理文件。 因此,FOS提供了创建模拟文件夹的能力,其本质上来说是创建了一个size为0的Object。对于这个Object可以上传下载,只是控制台会对以”/“结尾的Object以文件夹的方式展示。 用户可以通过 Delimiter 和 Prefix 参数的配合模拟出文件夹功能。Delimiter 和 Prefix 的组合效果是这样的: 如果把 Prefix 设为某个文件夹名,就可以罗列以此 Prefix 开头的文件,即该文件夹下递归的所有的文件和子文件夹(目录)。文件名在Contents中显示。 如果再把 Delimiter 设置为 “/” 时,返回值就只罗列该文件夹下的文件和子文件夹(目录),该文件夹下的子文件名(目录)返回在 CommonPrefixes 部分,子文件夹下递归的文件和文件夹不被显示。 如下是几个应用方式: 列出Bucket内所有文件 当用户需要获取Bucket下的所有文件时,可以参考分页获取所有Object 递归列出目录下所有文件 可以通过设置 Prefix 参数来获取某个目录下所有的文件:

java
// 构造ListObjectsRequest请求
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
// 递归列出fun目录下的所有文件
listObjectsRequest.setPrefix("fun/");
ListObjectsResponse listing = client.listObjects(listObjectsRequest);
// 遍历所有Object
System.out.println("Objects:");
for (FosObjectSummary objectSummary : listing.getContents()) {
    System.out.println(objectSummary.getKey());
}

输出:

java
Objects:
fun/
fun/movie/001.avi
fun/movie/007.avi
fun/test.jpg

查看目录下的文件和子目录 在 Prefix 和 Delimiter 结合的情况下,可以列出目录下的文件和子目录:

java
// 构造ListObjectsRequest请求
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
// "/" 为文件夹的分隔符
listObjectsRequest.setDelimiter("/");
// 列出fun目录下的所有文件和文件夹
listObjectsRequest.setPrefix("fun/");
ListObjectsResponse listing = client.listObjects(listObjectsRequest);
// 遍历所有Object
System.out.println("Objects:");
for (FosObjectSummary objectSummary : listing.getContents()) {
    System.out.println(objectSummary.getKey());
}
// 遍历所有CommonPrefix
System.out.println("\nCommonPrefixs:");
for (String commonPrefix : listing.getCommonPrefixes()) {
    System.out.println(commonPrefix);
}

输出:

java
Objects:
fun/
fun/test.jpg

CommonPrefixs:
fun/movie/

返回的结果中, ObjectSummaries 的列表中给出的是fun目录下的文件。而 CommonPrefixs 的列表中给出的是fun目录下的所有子文件夹。可以看出 fun/movie/001.avi , fun/movie/007.avi 两个文件并没有被列出来,因为它们属于 fun 文件夹下的 movie 目录。