从 Java 中删除“文件夹”中或 Google Cloud Bucket 中带有前缀的所有文件

我知道“文件夹”的概念在Google Cloud Storage中是不存在或不同的,但我需要一种方法来删除“文件夹”中的所有对象或Java中具有给定前缀的所有对象。

GcsService有一个删除功能,但据我所知,它只接受1个GscFilename对象,并且不支持通配符(即“folderName/**”不起作用)。

有什么提示吗?


答案 1

API 一次只支持删除一个对象。您只能使用多个 HTTP 请求或通过批处理多个删除请求来请求多个删除。没有 API 调用来使用通配符等删除多个对象。为了删除具有特定前缀的所有对象,您需要列出对象,然后对与模式匹配的每个对象进行删除调用。

命令行实用程序 gsutil 在您要求它删除路径“gs://bucket/dir/**时,正是这样做的。它获取与该模式匹配的对象列表,然后为每个对象进行删除调用。

如果你需要一个快速的解决方案,你总是可以让你的Java程序执行官官。

以下是与上述答案相对应的代码,以防其他人想要使用它:

public void deleteFolder(String bucket, String folderName) throws CoultNotDeleteFile {
  try
  {
    ListResult list = gcsService.list(bucket, new ListOptions.Builder().setPrefix(folderName).setRecursive(true).build());

    while(list.hasNext())
    {
      ListItem item = list.next();
      gcsService.delete(new GcsFilename(file.getBucket(), item.getName()));
    }
  }
  catch (IOException e)
  {
    //Error handling
  }
}

答案 2

派对非常晚,但这是当前的谷歌搜索。我们可以通过利用com.google.cloud.storage.StorageBatch有效地删除多个blob。

这样:

public static void rmdir(Storage storage, String bucket, String dir) {
    StorageBatch batch = storage.batch();
    Page<Blob> blobs = storage.list(bucket, Storage.BlobListOption.currentDirectory(),
            Storage.BlobListOption.prefix(dir));
    for(Blob blob : blobs.iterateAll()) {
        batch.delete(blob.getBlobId());
    }
    batch.submit();
}

这应该比当您的存储桶/文件夹包含大量项目时逐个删除要快得多

编辑,因为这引起了一点关注,我将演示错误处理:

public static boolean rmdir(Storage storage, String bucket, String dir) {
    List<StorageBatchResult<Boolean>> results = new ArrayList<>();
    StorageBatch batch = storage.batch();
    try {
        Page<Blob> blobs = storage.list(bucket, Storage.BlobListOption.currentDirectory(),
            Storage.BlobListOption.prefix(dir));
        for(Blob blob : blobs.iterateAll()) {
            results.add(batch.delete(blob.getBlobId()));
        }
    } finally {
        batch.submit();
        return results.stream().allMatch(r -> r != null && r.get());
    }
}

此方法将:删除给定存储桶的给定文件夹中的每个 blob,如果返回 true,则返回 true。否则,该方法将返回 false。可以查看 batch.delete() 的返回方法,以便更好地理解和防错。

要确保删除所有项目,您可以按如下方式调用:

boolean success = false
while(!success)) {
    success = rmdir(storage, bucket, dir);
}

推荐