列出 Cloud Storage 文件(Apple 平台)

借助 Cloud Storage for Firebase,您可以列出 Cloud Storage 存储桶的内容。SDK 会返回当前 Cloud Storage 引用下的对象的项和前缀。

对于使用 List API 的项目,需要使用 Cloud Storage for Firebase 规则版本 2。如果您已有一个 Firebase 项目,请按照安全规则指南中的步骤操作。

list() 使用 Google Cloud Storage List API。在 Cloud Storage for Firebase 中,我们使用 / 作为分隔符来模拟文件系统语义。为了高效遍历大型分层 Cloud Storage 存储桶,List API 会将前缀和项分开返回。例如,如果您上传一个文件 /images/uid/file1,则:

  • root.child('images').listAll() 将返回 /images/uid 作为前缀。
  • root.child('images/uid').listAll() 将返回该文件作为项。

Cloud Storage for Firebase SDK 不会返回包含两个连续的 / 或以 /. 结尾的对象路径。例如,假设一个存储桶中包含以下对象:

  • correctPrefix/happyItem
  • wrongPrefix//sadItem
  • lonelyItem/

对此存储桶中的项执行列出操作返回的结果如下:

  • 在根目录中执行列出操作将返回对 correctPrefixwrongPrefixlonelyItem 的引用作为 prefixes
  • correctPrefix/ 中执行列出操作将返回对 correctPrefix/happyItem 的引用作为 items
  • wrongPrefix/ 中执行列出操作不会返回任何引用,因为 wrongPrefix//sadItem 包含两个连续的 /
  • lonelyItem/ 中执行列出操作不会返回任何引用,因为对象 lonelyItem// 结尾。

列出所有文件

您可以使用 listAll(completion:) 提取某个目录的所有结果。此方法最适合用于小型目录,因为所有结果都会保留在内存缓冲区中。如果在操作期间系统添加或移除了对象,该操作也可能不会返回一致的快照。

由于 listAll(completion:) 会在内存缓冲区中保留所有结果,大型列表更适合使用分页的 list(withMaxResults:completion:) 方法。

以下示例演示了 listAll(completion:)

Swift

let storageReference = storage.reference().child("files/uid")
do {
  let result = try await storageReference.listAll()
  for prefix in result.prefixes {
    // The prefixes under storageReference.
    // You may call listAll(completion:) recursively on them.
  }
  for item in result.items {
    // The items under storageReference.
  }
} catch {
  // ...
}

Objective-C

FIRStorageReference *storageReference = [storage reference];
[storageReference listAllWithCompletion:^(FIRStorageListResult *result, NSError *error) {
  if (error != nil) {
    // ...
  }

  for (FIRStorageReference *prefix in result.prefixes) {
    // All the prefixes under storageReference.
    // You may call listAllWithCompletion: recursively on them.
  }
  for (FIRStorageReference *item in result.items) {
    // All items under storageReference.
  }
}];

将列出的结果分页

list(withMaxResults:completion:) API 对返回的结果数设置了限制。list(withMaxResults:completion) 会提供一致的分页视图,并提供一个让您可以控制何时提取更多结果的 pageToken。

该 pageToken 会对上一条结果中返回的最后一项的路径和版本进行编码。在后续请求中使用该 pageToken,系统会返回位于该 pageToken 后面的项。

下面的示例演示了如何对结果进行分页:

Swift

func listAllPaginated(pageToken: String? = nil) async throws {
  let storage = Storage.storage()
  let storageReference = storage.reference().child("files/uid")

  let listResult: StorageListResult
  if let pageToken = pageToken {
    listResult = try await storageReference.list(maxResults: 100, pageToken: pageToken)
  } else {
    listResult = try await storageReference.list(maxResults: 100)
  }
  let prefixes = listResult.prefixes
  let items = listResult.items
  // Handle list result
  // ...

  // Process next page
  if let token = listResult.pageToken {
    try await listAllPaginated(pageToken: token)
  }
}

Objective-C

- (void)paginateFilesAtReference:(FIRStorageReference *)reference
                       pageToken:(nullable NSString *)pageToken {
  void (^pageHandler)(FIRStorageListResult *_Nonnull, NSError *_Nullable) =
      ^(FIRStorageListResult *result, NSError *error) {
        if (error != nil) {
          // ...
        }
        NSArray *prefixes = result.prefixes;
        NSArray *items = result.items;

        // ...

        // Process next page
        if (result.pageToken != nil) {
          [self paginateFilesAtReference:reference pageToken:result.pageToken];
        }
  };

  if (pageToken != nil) {
    [reference listWithMaxResults:100 pageToken:pageToken completion:pageHandler];
  } else {
    [reference listWithMaxResults:100 completion:pageHandler];
  }
}

处理错误

如果您尚未将安全规则升级到版本 2,List API 中的方法将失败。如果您看到以下错误消息,请升级您的安全规则:

Listing objects in a bucket is disallowed for rules_version = "1".
Please update storage security rules to rules_version = "2" to use list.

系统也可能会显示其他错误消息,指出用户没有适当的权限。如需详细了解这些错误,请参阅处理错误