如何使用 C# 中的 AWSSDK.S3 解析 AWS S3 路径 (s3://<bucket name>/<key>) 以获取存储桶名称和密钥
How to parse the AWS S3 Path (s3://<bucket name>/<key>) using the AWSSDK.S3 in C# in order to get the bucket name & key
我有一个 s3 路径 => s3://[bucket name]/[key]
s3://bn-complete-dev-test/1234567890/renders/Irradiance_A.png
我需要分别获取 bucket_name 和密钥:
var s3PathParsed = parseS3Path("s3://bn-complete-dev-test/1234567890/renders/Irradiance_A.png");
s3PathParsed.BucketName == "bn-complete-dev-test"
s3PathParsed.Key == "1234567890/renders/Irradiance_A.png"
如何使用 AWS SDK以正确的方式解析?
1) 我正在手动解析(使用正则表达式)并且 工作正常但我不舒服:
public class S3Path : IS3Path
{
private const string _s3PathRegex = @"[s|S]3:\/\/(?<bucket>[^\/]*)\/(?<key>.*)";
public S3Path(string s3Path)
{
Path = s3Path;
var rx = new Regex(_s3PathRegex).Match(s3Path);
if (!rx.Success || rx.Groups.Count != 3)
throw new Exception($"the S3 Path '{s3Path}' is wrong.");
BucketName = rx.Groups[1].Value;
Key = rx.Groups[2].Value;
}
public string Path { get; }
public string BucketName { get; }
public string Key { get; }
}
2) 我使用了 AWWSDK.S3 中的 AmazonS3Uri:
string GetBucketNameFromS3Uri(string s3Uri)
{
return new AmazonS3Uri(s3Uri).Bucket;
}
我调用了方法:
GetBucketNameFromS3Uri("s3://sunsite-complete-dev-test/1234567890/renders/Irradiance_A.png");
我有以下错误:
System.ArgumentException: 'Invalid S3 URI - hostname does not appear to be a valid S3 endpoint'
3) 我也试试
string GetBucketNameFromS3Uri(string s3Uri)
{
return new AmazonS3Uri(new Uri(s3Uri)).Bucket;
}
同样的错误。
我在 AWS 论坛中针对此问题创建了一个新线程:https://forums.aws.amazon.com/thread.jspa?threadID=304401
我相信这个正则表达式会给你想要的:
s3:\/\/(?<bucket>[^\/]*)\/(?<key>.*)
存储桶名称是 S3 路径的第一部分,键是第一个正斜杠后的所有内容。
AWSSDK.S3没有路径解析器,需要手动解析。您可以使用以下 class 效果很好的方法:
public class S3Path
{
private const string _s3PathRegex = @"[s|S]3:\/\/(?<bucket>[^\/]+)\/(?<key>.+)";
public S3Path(string s3Path)
{
Path = s3Path;
var rx = new Regex(_s3PathRegex).Match(s3Path);
if (!rx.Success)
throw new Exception($"the S3 Path '{s3Path}' is wrong.");
BucketName = rx.Groups["bucket"].Value;
Key = rx.Groups["key"].Value;
}
public string Path { get; }
public string BucketName { get; }
public string Key { get; }
}
I created a thread in AWS Forum 报告缺少的功能。
这是正则表达式的 Scala 版本和用法。
val regex = "s3a://([^/]*)/(.*)".r
val regex(bucketName, key) = "s3a://my-bucket-name/myrootpath/mychildpath/file.json"
println(bucketName) // my-bucket-name
println(key) // myrootpath/mychildpath/file.json
在Java中,我们可以做类似
的事情
AmazonS3URI s3URI = new AmazonS3URI("s3://bucket/folder/object.csv");
S3Object s3Object = s3Client.getObject(s3URI.getBucket(), s3URI.getKey());
如果你有对象URL (https://bn-complete-dev-test.s3.eu-west-2.amazonaws.com/1234567890/renders/Irradiance_A.pnlet
),你可以使用AmazonS3Uri
:
// using Amazon.S3.Util
var uri = new AmazonS3Uri(urlString);
var bucketName = uri.Bucket;
var key = uri.Key;
如果你有一个 S3 URI (s3://bn-complete-dev-test/1234567890/renders/Irradiance_A.png
) 那么它就有点复杂了:
using System;
public static class S3
{
public static Tuple<string, string> TryParseS3Uri(string x)
{
try
{
var uri = new Uri(x);
if (uri.Scheme == "s3")
{
var bucket = uri.Host;
var key = uri.LocalPath.Substring(1);
return new Tuple<string, string>(bucket, key);
}
return null;
}
catch (Exception ex)
{
var ex2 = ex as UriFormatException;
if (ex2 == null)
{
throw ex;
}
return null;
}
}
}
这是一个 F# 版本:
open System
let tryParseS3Uri (x : string) =
try
let uri = Uri x
if uri.Scheme = "s3"
then
let bucket = uri.Host
let key = uri.LocalPath.Substring 1
Some (bucket, key)
else
None
with
| :? UriFormatException -> None
| exn -> raise exn
对于 Javascript 版本,您可以使用 amazon-s3-uri
const AmazonS3URI = require('amazon-s3-uri')
try {
const uri = 'https://bucket.s3-aws-region.amazonaws.com/key'
const { region, bucket, key } = AmazonS3URI(uri)
} catch((err) => {
console.warn(`${uri} is not a valid S3 uri`) // should not happen because `uri` is valid in that example
})
使用AWSSDK.S3
public (string bucket, string objectKey, Amazon.RegionEndpoint region) Parse(string s3)
{
if (!Amazon.S3.Util.AmazonS3Uri.TryParseAmazonS3Uri(s3, out Amazon.S3.Util.AmazonS3Uri s3Uri))
{
throw new System.ArgumentOutOfRangeException(nameof(s3));
}
return (s3Uri.Bucket, s3Uri.Key, s3Uri.Region);
}
我有一个 s3 路径 => s3://[bucket name]/[key]
s3://bn-complete-dev-test/1234567890/renders/Irradiance_A.png
我需要分别获取 bucket_name 和密钥:
var s3PathParsed = parseS3Path("s3://bn-complete-dev-test/1234567890/renders/Irradiance_A.png");
s3PathParsed.BucketName == "bn-complete-dev-test"
s3PathParsed.Key == "1234567890/renders/Irradiance_A.png"
如何使用 AWS SDK以正确的方式解析?
1) 我正在手动解析(使用正则表达式)并且 工作正常但我不舒服:
public class S3Path : IS3Path
{
private const string _s3PathRegex = @"[s|S]3:\/\/(?<bucket>[^\/]*)\/(?<key>.*)";
public S3Path(string s3Path)
{
Path = s3Path;
var rx = new Regex(_s3PathRegex).Match(s3Path);
if (!rx.Success || rx.Groups.Count != 3)
throw new Exception($"the S3 Path '{s3Path}' is wrong.");
BucketName = rx.Groups[1].Value;
Key = rx.Groups[2].Value;
}
public string Path { get; }
public string BucketName { get; }
public string Key { get; }
}
2) 我使用了 AWWSDK.S3 中的 AmazonS3Uri:
string GetBucketNameFromS3Uri(string s3Uri)
{
return new AmazonS3Uri(s3Uri).Bucket;
}
我调用了方法:
GetBucketNameFromS3Uri("s3://sunsite-complete-dev-test/1234567890/renders/Irradiance_A.png");
我有以下错误:
System.ArgumentException: 'Invalid S3 URI - hostname does not appear to be a valid S3 endpoint'
3) 我也试试
string GetBucketNameFromS3Uri(string s3Uri)
{
return new AmazonS3Uri(new Uri(s3Uri)).Bucket;
}
同样的错误。
我在 AWS 论坛中针对此问题创建了一个新线程:https://forums.aws.amazon.com/thread.jspa?threadID=304401
我相信这个正则表达式会给你想要的:
s3:\/\/(?<bucket>[^\/]*)\/(?<key>.*)
存储桶名称是 S3 路径的第一部分,键是第一个正斜杠后的所有内容。
AWSSDK.S3没有路径解析器,需要手动解析。您可以使用以下 class 效果很好的方法:
public class S3Path
{
private const string _s3PathRegex = @"[s|S]3:\/\/(?<bucket>[^\/]+)\/(?<key>.+)";
public S3Path(string s3Path)
{
Path = s3Path;
var rx = new Regex(_s3PathRegex).Match(s3Path);
if (!rx.Success)
throw new Exception($"the S3 Path '{s3Path}' is wrong.");
BucketName = rx.Groups["bucket"].Value;
Key = rx.Groups["key"].Value;
}
public string Path { get; }
public string BucketName { get; }
public string Key { get; }
}
I created a thread in AWS Forum 报告缺少的功能。
这是正则表达式的 Scala 版本和用法。
val regex = "s3a://([^/]*)/(.*)".r
val regex(bucketName, key) = "s3a://my-bucket-name/myrootpath/mychildpath/file.json"
println(bucketName) // my-bucket-name
println(key) // myrootpath/mychildpath/file.json
在Java中,我们可以做类似
的事情AmazonS3URI s3URI = new AmazonS3URI("s3://bucket/folder/object.csv");
S3Object s3Object = s3Client.getObject(s3URI.getBucket(), s3URI.getKey());
如果你有对象URL (https://bn-complete-dev-test.s3.eu-west-2.amazonaws.com/1234567890/renders/Irradiance_A.pnlet
),你可以使用AmazonS3Uri
:
// using Amazon.S3.Util
var uri = new AmazonS3Uri(urlString);
var bucketName = uri.Bucket;
var key = uri.Key;
如果你有一个 S3 URI (s3://bn-complete-dev-test/1234567890/renders/Irradiance_A.png
) 那么它就有点复杂了:
using System;
public static class S3
{
public static Tuple<string, string> TryParseS3Uri(string x)
{
try
{
var uri = new Uri(x);
if (uri.Scheme == "s3")
{
var bucket = uri.Host;
var key = uri.LocalPath.Substring(1);
return new Tuple<string, string>(bucket, key);
}
return null;
}
catch (Exception ex)
{
var ex2 = ex as UriFormatException;
if (ex2 == null)
{
throw ex;
}
return null;
}
}
}
这是一个 F# 版本:
open System
let tryParseS3Uri (x : string) =
try
let uri = Uri x
if uri.Scheme = "s3"
then
let bucket = uri.Host
let key = uri.LocalPath.Substring 1
Some (bucket, key)
else
None
with
| :? UriFormatException -> None
| exn -> raise exn
对于 Javascript 版本,您可以使用 amazon-s3-uri
const AmazonS3URI = require('amazon-s3-uri')
try {
const uri = 'https://bucket.s3-aws-region.amazonaws.com/key'
const { region, bucket, key } = AmazonS3URI(uri)
} catch((err) => {
console.warn(`${uri} is not a valid S3 uri`) // should not happen because `uri` is valid in that example
})
使用AWSSDK.S3
public (string bucket, string objectKey, Amazon.RegionEndpoint region) Parse(string s3)
{
if (!Amazon.S3.Util.AmazonS3Uri.TryParseAmazonS3Uri(s3, out Amazon.S3.Util.AmazonS3Uri s3Uri))
{
throw new System.ArgumentOutOfRangeException(nameof(s3));
}
return (s3Uri.Bucket, s3Uri.Key, s3Uri.Region);
}