C# 根据通配符确定S3存储桶中是否存在对象
有人能告诉我如何确定某个文件/对象是否存在于S3存储桶中,并显示一条消息(如果存在或不存在) 基本上,我希望它: 1) 在我的S3帐户上检查一个bucket,比如testbucket 2) 在该bucket中,查看是否有前缀为test_u的文件(test_file.txt或test_data.txt) 3) 如果该文件存在,则显示一条消息框(或控制台消息),表明该文件存在,或该文件不存在C# 根据通配符确定S3存储桶中是否存在对象,c#,amazon-s3,C#,Amazon S3,有人能告诉我如何确定某个文件/对象是否存在于S3存储桶中,并显示一条消息(如果存在或不存在) 基本上,我希望它: 1) 在我的S3帐户上检查一个bucket,比如testbucket 2) 在该bucket中,查看是否有前缀为test_u的文件(test_file.txt或test_data.txt) 3) 如果该文件存在,则显示一条消息框(或控制台消息),表明该文件存在,或该文件不存在 有人能告诉我怎么做吗?使用.Net的AWSSDK,我目前做了以下几点: public bool Exists
有人能告诉我怎么做吗?使用.Net的AWSSDK,我目前做了以下几点:
public bool Exists(string fileKey, string bucketName)
{
try
{
response = _s3Client.GetObjectMetadata(new GetObjectMetadataRequest()
.WithBucketName(bucketName)
.WithKey(key));
return true;
}
catch (Amazon.S3.AmazonS3Exception ex)
{
if (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
return false;
//status wasn't not found, so throw the exception
throw;
}
}
它有点差劲,但目前还可以使用。我不熟悉C,但我使用Java中的这种方法(转换为C是即时的):
这就解决了这个问题:
列出现有对象的bucket并使用类似的前缀
var request = new ListObjectsRequest()
.WithBucketName(_bucketName)
.WithPrefix(keyPrefix);
var response = _amazonS3Client.ListObjects(request);
var exists = response.S3Objects.Count > 0;
foreach (var obj in response.S3Objects) {
// act
}
使用以下方法:
我知道这个问题有几年历史了,但是新的SDK很好地处理了这个问题。如果有人还在搜索这个。你在找课吗
如果文件存在,它将返回数组我在C#和Amazon S3版本3.1.5(.net 3.5)中使用了以下代码来检查bucket是否存在:
BasicAWSCredentials credentials = new BasicAWSCredentials("accessKey", "secretKey");
AmazonS3Config configurationAmazon = new AmazonS3Config();
configurationAmazon.RegionEndpoint = S3Region.EU; // or you can use ServiceUrl
AmazonS3Client s3Client = new AmazonS3Client(credentials, configurationAmazon);
S3DirectoryInfo directoryInfo = new S3DirectoryInfo(s3Client, bucketName);
bucketExists = directoryInfo.Exists;// true if the bucket exists in other case false.
我使用了以下代码(在C#中,AmazonS3版本为3.1.5.NET3.5)文件存在
备选案文1:
S3FileInfo info = new S3FileInfo(s3Client, "butcketName", "key");
bool fileExists = info.Exists; // true if the key Exists in other case false
备选案文2:
ListObjectsRequest request = new ListObjectsRequest();
try
{
request.BucketName = "bucketName";
request.Prefix = "prefix"; // or part of the key
request.MaxKeys = 1; // max limit to find objects
ListObjectsResponse response = s3Client .ListObjects(request);
return response.S3Objects.Count > 0;
}
试试这个:
NameValueCollection appConfig = ConfigurationManager.AppSettings;
AmazonS3 s3Client = AWSClientFactory.CreateAmazonS3Client(
appConfig["AWSAccessKey"],
appConfig["AWSSecretKey"],
Amazon.RegionEndpoint.USEast1
);
S3DirectoryInfo source = new S3DirectoryInfo(s3Client, "BUCKET_NAME", "Key");
if(source.Exist)
{
//do ur stuff
}
我知道这个问题已经有几年历史了,但是现在新的SDK以更简单的方式处理这个问题
public async Task<bool> ObjectExistsAsync(string prefix)
{
var response = await _amazonS3.GetAllObjectKeysAsync(_awsS3Configuration.BucketName, prefix, null);
return response.Count > 0;
}
public异步任务ObjectExistsAsync(字符串前缀)
{
var response=await _amazonS3.getAllObjectKeyAsync(_awsS3Configuration.BucketName,前缀,null);
返回响应。计数>0;
}
其中,\u amazonS3
是您的IAmazonS3
实例,\u awss3配置。BucketName
是您的bucket名称
您可以使用完整密钥作为前缀。不确定这是否适用于.NET Framework,但AWS SDK(v3)的.NET核心版本仅支持异步请求,因此我不得不使用稍微不同的解决方案:
/// <summary>
/// Determines whether a file exists within the specified bucket
/// </summary>
/// <param name="bucket">The name of the bucket to search</param>
/// <param name="filePrefix">Match files that begin with this prefix</param>
/// <returns>True if the file exists</returns>
public async Task<bool> FileExists(string bucket, string filePrefix)
{
// Set this to your S3 region (of course)
var region = Amazon.RegionEndpoint.USEast1;
using (var client = new AmazonS3Client(region))
{
var request = new ListObjectsRequest {
BucketName = bucket,
Prefix = filePrefix,
MaxKeys = 1
};
var response = await client.ListObjectsAsync(request, CancellationToken.None);
return response.S3Objects.Any();
}
}
GetFileSystemInfo有一个重载 注意这一行有文件名* var files=s3DirectoryInfo.GetFileSystemInfos(“filename.*”)强>
public bool Check()
{
var awsCredentials = new Amazon.Runtime.BasicAWSCredentials("AccessKey", "SecretKey");
using (var client = new AmazonS3Client(awsCredentials, Amazon.RegionEndpoint.USEast1))
{
S3DirectoryInfo s3DirectoryInfo = new S3DirectoryInfo(client, bucketName, "YourFilePath");
var files= s3DirectoryInfo.GetFileSystemInfos("filename.*");
if(files.Any())
{
//fles exists
}
}
}
将throw(ex)更改为普通的旧throw。我不知道这如何回答使用通配符的问题。如何检查是否存在前缀相同的文件?这里有几个问题。首先,该技术不支持基于公共前缀的匹配对象。第二,一个相当常见的执行路径(文件不存在)将导致抛出异常-这会影响性能。这个答案来自2010年-SDK现在支持存在-如果我错了,有人会纠正我,但我相信这将为0字节返回false(空)如果密钥不存在,则将抛出AmazonS3Exception异常,并显示消息“禁止403”。相当愚蠢的东西。。。但是,如果我们确信我们可以访问bucket,我们可以将其视为“false”。这是一个比当前最高评级的on好得多的解决方案,因为它不使用异常来驱动逻辑。这将是更高的性能。@PavelShkleinik-github上提供的源代码是最近的:-我相信你所说的不再是事实。幸运的是,如果你在bucket中没有ListObjects权限,你将得到403。否则,404与非404错误可能会导致不必要的信息泄露。我知道这是一个旧答案,请注意,此解决方案基于一个异常,它使用GetObjectMetadata,如果文件不存在,它会引发一个异常使用ListObjectsRequest,这是不好的。值得注意的是,这是针对.NETCore的
NameValueCollection appConfig = ConfigurationManager.AppSettings;
AmazonS3 s3Client = AWSClientFactory.CreateAmazonS3Client(
appConfig["AWSAccessKey"],
appConfig["AWSSecretKey"],
Amazon.RegionEndpoint.USEast1
);
S3DirectoryInfo source = new S3DirectoryInfo(s3Client, "BUCKET_NAME", "Key");
if(source.Exist)
{
//do ur stuff
}
public async Task<bool> ObjectExistsAsync(string prefix)
{
var response = await _amazonS3.GetAllObjectKeysAsync(_awsS3Configuration.BucketName, prefix, null);
return response.Count > 0;
}
/// <summary>
/// Determines whether a file exists within the specified bucket
/// </summary>
/// <param name="bucket">The name of the bucket to search</param>
/// <param name="filePrefix">Match files that begin with this prefix</param>
/// <returns>True if the file exists</returns>
public async Task<bool> FileExists(string bucket, string filePrefix)
{
// Set this to your S3 region (of course)
var region = Amazon.RegionEndpoint.USEast1;
using (var client = new AmazonS3Client(region))
{
var request = new ListObjectsRequest {
BucketName = bucket,
Prefix = filePrefix,
MaxKeys = 1
};
var response = await client.ListObjectsAsync(request, CancellationToken.None);
return response.S3Objects.Any();
}
}
/// <summary>
/// Determines whether a file exists within the specified folder
/// </summary>
/// <param name="bucket">The name of the bucket to search</param>
/// <param name="folder">The name of the folder to search</param>
/// <param name="filePrefix">Match files that begin with this prefix</param>
/// <returns>True if the file exists</returns>
public async Task<bool> FileExists(string bucket, string folder, string filePrefix)
{
return await FileExists(bucket, $"{folder}/{filePrefix}");
}
var testExists = await FileExists("testBucket", "test_");
// or...
var testExistsInFolder = await FileExists("testBucket", "testFolder/testSubFolder", "test_");
using Amazon;
using Amazon.S3;
using Amazon.S3.IO;
using Amazon.S3.Model;
string accessKey = "xxxxx";
string secretKey = "xxxxx";
string regionEndpoint = "EU-WEST-1";
string bucketName = "Bucket1";
string filePath = "https://Bucket1/users/delivery/file.json"
public bool FileExistsOnS3(string filePath)
{
try
{
Uri myUri = new Uri(filePath);
string absolutePath = myUri.AbsolutePath; // /users/delivery/file.json
string key = absolutePath.Substring(1); // users/delivery/file.json
using(var client = AWSClientFactory.CreateAmazonS3Client(accessKey, secretKey, regionEndpoint))
{
S3FileInfo file = new S3FileInfo(client, bucketName, key);
if (file.Exists)
{
return true;
// custom logic
}
else
{
return false;
// custom logic
}
}
}
catch(AmazonS3Exception ex)
{
return false;
}
}
public bool Check()
{
var awsCredentials = new Amazon.Runtime.BasicAWSCredentials("AccessKey", "SecretKey");
using (var client = new AmazonS3Client(awsCredentials, Amazon.RegionEndpoint.USEast1))
{
S3DirectoryInfo s3DirectoryInfo = new S3DirectoryInfo(client, bucketName, "YourFilePath");
var files= s3DirectoryInfo.GetFileSystemInfos("filename.*");
if(files.Any())
{
//fles exists
}
}
}