删除"文件夹"中的所有文件或使用Java中的Google Cloud Bucket中的前缀

shi*_*roy 9 java google-cloud-storage google-cloud-endpoints

我知道Google云端存储中"文件夹"的概念是不存在或不同的,但我需要一种方法来删除"文件夹"中的所有对象或使用Java中的给定前缀.

GcsService有一个删除功能,但据我所知它只需要1个GscFilename对象而且不支持通配符(即"folderName/**"不起作用).

有小费吗?

小智 8

我意识到这是一个老问题,但我偶然发现了同样的问题并找到了解决它的不同方法。

Storage类中的谷歌云计算的Java客户端存储的方法包括列出在桶中的斑点,这也是可以接受的选项前缀筛选结果设置为斑点名称开头的前缀。

例如,从存储桶中删除具有给定前缀的所有文件可以这样实现:

Storage storage = StorageOptions.getDefaultInstance().getService();
Iterable<Blob> blobs = storage.list("bucket_name", Storage.BlobListOption.prefix("prefix")).iterateAll();
for (Blob blob : blobs) {
    blob.delete(Blob.BlobSourceOption.generationMatch());
}
Run Code Online (Sandbox Code Playgroud)


Bra*_*ugh 6

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

当你要求它删除路径"gs:// bucket/dir/**时,命令行实用程序gsutil就是这样做的.它获取与该模式匹配的对象列表,然后对每个模块进行删除调用.他们.

如果您需要快速解决方案,您可以始终拥有Java程序exec gsutil.

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

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
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,对象列表最终是一致的,这意味着如果最近创建了这些方法,则无法保证捕获所有对象.


Mee*_*tan 5

晚会来晚了,但是这里是针对当前的Google搜索。我们可以利用来有效地删除多个Blob com.google.cloud.storage.StorageBatch

像这样:

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();
}
Run Code Online (Sandbox Code Playgroud)

这应该运行MUCH快于删除一个接一个,当你的水桶/文件夹中包含的项目的不平凡量。

进行编辑,因为这引起了一些注意,我将演示错误处理:

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());
}
Run Code Online (Sandbox Code Playgroud)

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

为了确保所有项目都被删除,您可以这样称呼:

boolean success = false
while(!success)) {
    success = rmdir(storage, bucket, dir);
}
Run Code Online (Sandbox Code Playgroud)