Amazon S3:如何获取存储桶中的文件夹列表?
Amazon S3: How to get a list of folders in the bucket?
我唯一找到的就是这个方法GET Bucket。
但我不明白如何才能只获取当前文件夹中的文件夹列表。我需要使用什么前缀和分隔符?这可能吗?
举例来说,假设我在 USEast1
区域中有一个名为 MyBucketName
的存储桶,其中包含以下键:
temp/
temp/foobar.txt
temp/txt/
temp/txt/test1.txt
temp/txt/test2.txt
temp2/
使用文件夹可能会造成混淆,因为 S3 本身不支持层次结构——相反,这些只是像任何其他 S3 对象一样的键。文件夹只是 S3 Web 控制台中可用的抽象概念,可以更轻松地浏览存储桶。因此,当我们以编程方式工作时,我们希望找到与 'folder'(定界符 '/',大小 = 0)的维度匹配的键,因为它们很可能是 'folders',如 S3 提供给我们的那样控制台。
两个示例的注意事项:我使用的是 AWSSDK.S3 版本 3.1 NuGet 包。
示例 1:存储桶中的所有文件夹
此代码修改自 S3 文档中的 this basic example,以列出存储桶中的所有键。下面的示例将识别所有以定界字符 /
结尾并且也为空的键。
IAmazonS3 client;
using (client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1))
{
// Build your request to list objects in the bucket
ListObjectsRequest request = new ListObjectsRequest
{
BucketName = "MyBucketName"
};
do
{
// Build your call out to S3 and store the response
ListObjectsResponse response = client.ListObjects(request);
// Filter through the response to find keys that:
// - end with the delimiter character '/'
// - are empty.
IEnumerable<S3Object> folders = response.S3Objects.Where(x =>
x.Key.EndsWith(@"/") && x.Size == 0);
// Do something with your output keys. For this example, we write to the console.
folders.ToList().ForEach(x => System.Console.WriteLine(x.Key));
// If the response is truncated, we'll make another request
// and pull the next batch of keys
if (response.IsTruncated)
{
request.Marker = response.NextMarker;
}
else
{
request = null;
}
} while (request != null);
}
控制台的预期输出:
temp/
temp/txt/
temp2/
示例 2:匹配指定前缀的文件夹
您可以通过在 ListObjectsRequest.
上设置 Prefix
属性 进一步限制它仅检索与指定 Prefix
匹配的文件夹
ListObjectsRequest request = new ListObjectsRequest
{
BucketName = "MyBucketName",
Prefix = "temp/"
};
当应用于示例 1 时,我们期望得到以下输出:
temp/
temp/txt/
进一步阅读:
使用 the/path/to/read/
的 prefix
(请注意 没有 前导斜杠,但 是 斜杠)和 /
的 delimiter
,您将在 <CommonPrefixes>
.
中找到该文件夹内的所有文件夹
CommonPrefixes
A response can contain CommonPrefixes
only if you specify a delimiter. When you do, CommonPrefixes
contains all (if there are any) keys between Prefix and the next occurrence of the string specified by delimiter. In effect, CommonPrefixes lists keys that act like subdirectories in the directory specified by Prefix
. For example, if prefix is notes/ and delimiter is a slash (/), in notes/summer/july, the common prefix is notes/summer/. All of the keys rolled up in a common prefix count as a single return when calculating the number of returns. See MaxKeys.
http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html
或者另一种更简单的方法是使用 https://github.com/minio/minio-dotnet
Minio .Net 实现了最小的 API 来与 Amazon S3 和其他兼容的存储解决方案一起工作。
以下示例显示了如何仅过滤掉目录。这里通过ListObjects()API将CommonPrefix抽象为一个文件夹。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Minio;
using Minio.Xml;
namespace Minio.Examples
{
class ListObjects
{
static int Main(string[] args)
{
var client = new MinioClient("https://s3.amazonaws.com", "ACCESSKEY", "SECRETKEY");
var items = client.ListObjects("bucket");
foreach (Item item in items)
{
if (item.IsDir)
{
Console.Out.WriteLine("{0}", item.Key);
}
}
return 0;
}
}
}
Anthony 在这里缺少的是文件夹不一定具有与之关联的密钥。如果一个文件是在 S3 中创建的,并且给定了一个像 "folder/name.ext" 这样的键,S3 将显示一个 "folder" 文件夹,但它没有键,这意味着您没有在结果中得到它。
捕获这些文件夹的唯一方法是查看键本身,并用正则表达式表示“/”字符的键名。如果我对 C# 了解多一点,我会为您写一个代码示例,但这里有一个 python example 我在另一个问题上写的供参考。
在我的参数中添加分隔符“/”对我有用。
如果有人需要 NodeJS 解决方案,这就是我使用的解决方案:
listdelim: function (path) {
const params = {
Bucket: process.env['bucket'],
MaxKeys: 1000,
Prefix: path,
Delimiter: '/'
}
return new Promise((resolve, reject) => {
s3.listObjectsV2(params, function (err, data) {
if (err) {
console.log(err, err.stack)
reject(err)
} else {
resolve(data)
}
})
})
}
我唯一找到的就是这个方法GET Bucket。
但我不明白如何才能只获取当前文件夹中的文件夹列表。我需要使用什么前缀和分隔符?这可能吗?
举例来说,假设我在 USEast1
区域中有一个名为 MyBucketName
的存储桶,其中包含以下键:
temp/
temp/foobar.txt
temp/txt/
temp/txt/test1.txt
temp/txt/test2.txt
temp2/
使用文件夹可能会造成混淆,因为 S3 本身不支持层次结构——相反,这些只是像任何其他 S3 对象一样的键。文件夹只是 S3 Web 控制台中可用的抽象概念,可以更轻松地浏览存储桶。因此,当我们以编程方式工作时,我们希望找到与 'folder'(定界符 '/',大小 = 0)的维度匹配的键,因为它们很可能是 'folders',如 S3 提供给我们的那样控制台。
两个示例的注意事项:我使用的是 AWSSDK.S3 版本 3.1 NuGet 包。
示例 1:存储桶中的所有文件夹
此代码修改自 S3 文档中的 this basic example,以列出存储桶中的所有键。下面的示例将识别所有以定界字符 /
结尾并且也为空的键。
IAmazonS3 client;
using (client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1))
{
// Build your request to list objects in the bucket
ListObjectsRequest request = new ListObjectsRequest
{
BucketName = "MyBucketName"
};
do
{
// Build your call out to S3 and store the response
ListObjectsResponse response = client.ListObjects(request);
// Filter through the response to find keys that:
// - end with the delimiter character '/'
// - are empty.
IEnumerable<S3Object> folders = response.S3Objects.Where(x =>
x.Key.EndsWith(@"/") && x.Size == 0);
// Do something with your output keys. For this example, we write to the console.
folders.ToList().ForEach(x => System.Console.WriteLine(x.Key));
// If the response is truncated, we'll make another request
// and pull the next batch of keys
if (response.IsTruncated)
{
request.Marker = response.NextMarker;
}
else
{
request = null;
}
} while (request != null);
}
控制台的预期输出:
temp/
temp/txt/
temp2/
示例 2:匹配指定前缀的文件夹
您可以通过在 ListObjectsRequest.
上设置Prefix
属性 进一步限制它仅检索与指定 Prefix
匹配的文件夹
ListObjectsRequest request = new ListObjectsRequest
{
BucketName = "MyBucketName",
Prefix = "temp/"
};
当应用于示例 1 时,我们期望得到以下输出:
temp/
temp/txt/
进一步阅读:
使用 the/path/to/read/
的 prefix
(请注意 没有 前导斜杠,但 是 斜杠)和 /
的 delimiter
,您将在 <CommonPrefixes>
.
CommonPrefixes
A response can contain
CommonPrefixes
only if you specify a delimiter. When you do,CommonPrefixes
contains all (if there are any) keys between Prefix and the next occurrence of the string specified by delimiter. In effect, CommonPrefixes lists keys that act like subdirectories in the directory specified byPrefix
. For example, if prefix is notes/ and delimiter is a slash (/), in notes/summer/july, the common prefix is notes/summer/. All of the keys rolled up in a common prefix count as a single return when calculating the number of returns. See MaxKeys.http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html
或者另一种更简单的方法是使用 https://github.com/minio/minio-dotnet
Minio .Net 实现了最小的 API 来与 Amazon S3 和其他兼容的存储解决方案一起工作。
以下示例显示了如何仅过滤掉目录。这里通过ListObjects()API将CommonPrefix抽象为一个文件夹。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Minio;
using Minio.Xml;
namespace Minio.Examples
{
class ListObjects
{
static int Main(string[] args)
{
var client = new MinioClient("https://s3.amazonaws.com", "ACCESSKEY", "SECRETKEY");
var items = client.ListObjects("bucket");
foreach (Item item in items)
{
if (item.IsDir)
{
Console.Out.WriteLine("{0}", item.Key);
}
}
return 0;
}
}
}
Anthony 在这里缺少的是文件夹不一定具有与之关联的密钥。如果一个文件是在 S3 中创建的,并且给定了一个像 "folder/name.ext" 这样的键,S3 将显示一个 "folder" 文件夹,但它没有键,这意味着您没有在结果中得到它。
捕获这些文件夹的唯一方法是查看键本身,并用正则表达式表示“/”字符的键名。如果我对 C# 了解多一点,我会为您写一个代码示例,但这里有一个 python example 我在另一个问题上写的供参考。
在我的参数中添加分隔符“/”对我有用。
如果有人需要 NodeJS 解决方案,这就是我使用的解决方案:
listdelim: function (path) {
const params = {
Bucket: process.env['bucket'],
MaxKeys: 1000,
Prefix: path,
Delimiter: '/'
}
return new Promise((resolve, reject) => {
s3.listObjectsV2(params, function (err, data) {
if (err) {
console.log(err, err.stack)
reject(err)
} else {
resolve(data)
}
})
})
}