3
votes

Comment analyser le chemin AWS S3 (s3: // <nom du compartiment> / <clé>) à l'aide de AWSSDK.S3 en C # afin d'obtenir le nom et la clé du compartiment

J'ai un chemin s3 => s3: // [nom du seau] / [clé]

string GetBucketNameFromS3Uri(string s3Uri)
{
    return new AmazonS3Uri(new Uri(s3Uri)).Bucket;            
}

et j'ai besoin d'obtenir le bucket_name et la clé séparément:

GetBucketNameFromS3Uri("s3://sunsite-complete-dev-test/1234567890/renders/Irradiance_A.png");

comment puis-je analyser correctement à l'aide du kit SDK AWS ?

1) J'analyse manuellement (en utilisant une expression régulière) et je travaille bien mais je ne suis pas à l'aise :

string GetBucketNameFromS3Uri(string s3Uri)
{
    return new AmazonS3Uri(s3Uri).Bucket;            
}

2) J'ai utilisé AmazonS3Uri d'AWWSDK.S3:

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; }
}

J'ai appelé la méthode:

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"

et j'ai l'erreur suivante:

System.ArgumentException: 'URI S3 non valide - le nom d'hôte ne semble pas être un point de terminaison S3 valide'

3) J'essaye aussi

s3://bn-complete-dev-test/1234567890/renders/Irradiance_A.png 

avec la même erreur.

J'ai créé un nouveau fil de discussion dans AWS Forum avec ce problème: https://forums.aws.amazon.com/thread.jspa?threadID=304401


2 commentaires

Il y a évidemment un problème avec l'URI S3 que vous utilisez. Pouvez-vous mettre à jour votre question pour inclure l'URI réel? Cela devrait être quelque chose comme https://bucket.s3-aws-region.amazonaws.com/key .


J'ai besoin d'analyser le chemin S3 (s3: // <bucket_name> / <key>), pas l'URL de l'objet


6 Réponses :


0
votes

Je crois que cette regex vous donnera ce que vous voulez:

s3:\/\/(?<bucket>[^\/]*)\/(?<key>.*)

Le nom du compartiment est la première partie du chemin S3 et la clé est tout après la première barre oblique.


3 commentaires

Je souhaite éviter l'utilisation de solutions manuelles comme les expressions régulières car il s'agit d'une méthode manuelle, je souhaite utiliser le kit AWS SDK pour S3


Malheureusement, je ne pense pas que vous allez déposer une solution dans le SDK Amazon car il semble s'attendre au format http://bucket.s3.aws-region.amazonaws.com/Key pour ses URI


Oui je suis d'accord. AWS SDK n'a pas cette fonctionnalité pour le moment.



0
votes

L'AWSSDK.S3 n'a pas d'analyseur de chemin, nous avons besoin d'analyser manuellement. Vous pouvez utiliser la classe suivante qui fonctionne correctement:

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; }
}

J'ai créé un fil de discussion dans AWS Forum pour signaler la fonctionnalité manquante.


2 commentaires

Vous ne pouvez pas avoir rx.Success == true et rx.Groups.Count être autre chose que 3. Sinon, il ne correspondrait pas à l'expression régulière. En outre, l'intérêt de nommer les groupes était que vous puissiez utiliser rx.Groups["Bucket"].Value et rx.Groups["Key"].Value .


Qu'en est-il de docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/TS3Uri.htm‌ l ?



1
votes

Voici la version scala et l'utilisation de l'expression régulière.

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


0 commentaires

6
votes

En Java, nous pouvons faire quelque chose comme

AmazonS3URI s3URI = new AmazonS3URI("s3://bucket/folder/object.csv");
S3Object s3Object = s3Client.getObject(s3URI.getBucket(), s3URI.getKey());


1 commentaires

Je ne savais pas que cet objet d'assistance existait. Bonne idée.



3
votes

Si vous avez une URL d'objet ( https://bn-complete-dev-test.s3.eu-west-2.amazonaws.com/1234567890/renders/Irradiance_A.pnlet ), vous pouvez utiliser AmazonS3Uri :

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

Si vous avez un URI S3 ( s3://bn-complete-dev-test/1234567890/renders/Irradiance_A.png ) alors c'est un peu plus 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;
        }
    }
}

Voici une version F #:

// using Amazon.S3.Util

var uri = new AmazonS3Uri(urlString); 

var bucketName = uri.Bucket;
var key = uri.Key;


2 commentaires

Cela ne fonctionne pas avec un chemin S3 comme "s3: //bn-complete-dev-test/1234567890/renders/Irradiance_A.p‌ ng". Cela ne fonctionne qu'avec l'URL de l'objet.


@Trisped Bon point. Nous pouvons utiliser la classe Uri de la bibliothèque standard pour cela.



0
votes

Pour la version Javascript, vous pouvez utiliser 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
})


0 commentaires