C#を利用したAWS S3操作まとめ

2020-09-18


はじめに

前回は、PowerShellでのAWS S3操作についてまとめました。

今回は、C#を利用したAWS S3操作のまとめとなります。C#で利用する場合は、「AWS SDK for .NET」を利用します。

本記事でも同様に、下記についてまとめておきます。

  • AWS S3Bucketの作成
  • AWS S3へのファイルアップロード
  • AWS S3のBucketおよびKey情報の取得
  • AWS S3からのファイルダウンロード
  • AWS S3からファイルを削除する

参考

V3 API Documentation

NuGetでのパッケージインストール

AWS S3の操作を行うために、NuGetよりAWSSDK.CoreおよびAWSSDK.S3のパッケージをインストールします。

本処理はVirual Studio 2019でプロジェクトを作成します。(プロジェクト作成部分は省きます)

1) [ツール]-[NuGet パッケージ マネージャー(N)]-[ソリューションのNuGetパッケージの管理(N)…]を選択する

2) [参照]を選択し、入力欄に「AWSSDK」と入力する。その後、「AWSSDK.Core」と「AWSSDK.S3」を必要なプロジェクトにインストールする

3) インストール済みに、先ほどインストールしたパッケージが表示されていることを確認します。

下準備

まずは、それぞれの操作を行う前に認証情報の設定を行います

private IAmazonS3 m_client;

/// <summary>
/// コンストラクタ
/// </summary>
public void Initialized()
{
    AmazonS3Config config = new AmazonS3Config();
    config.RegionEndpoint = RegionEndpoint.APNortheast1;

    // プロキシの設定を行う場合は、下記を設定
    config.ProxyHost = "127.0.0.1";
    config.ProxyPort = xxx;

    SharedCredentialsFile credentialsFile = new SharedCredentialsFile();
    CredentialProfile profile = null;

    if(credentialsFile.TryGetProfile("default", out profile) == false){
        Console.WriteLine("プロファイルの取得に失敗しました。");
        return;
    }

    AWSCredentials awsCredentials = null;
    if(AWSCredentialsFactory.TryGetAWSCredentials(profile, credentialsFile, out awsCredentials) == false){
        Console.WriteLine("認証情報の生成に失敗しました。");
    }

    m_client = new AmazonS3Client(awsCredentials, config);
}

ここでは、AWSCredentialsを引数としてAmazonS3Clientオブジェクトを作成していますが、
アクセスキーと秘密鍵を利用しても可能です。

AmazonS3Configで様々なオプションを設定できるので、プロファイルを作成しておき、そのプロファイルを読み込むようにしておくと、良いかと思います。

S3関連の関数を利用するために、usingで下記を定義しておきます。

using Amazon;
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using Amazon.S3.Util;
using Amazon.S3.Model;

これでとりあえず準備はOKです。

AWS S3Bucketの作成

早速S3Bucketを作成していきます。

Syntax

IAmazonS3.PutBucketAsync (string, CancellationToken)

public virtual Task<PutBucketResponse> PutBucketAsync(
         String bucketName,
         [CancellationToken cancellationToken]
)

IAmazonS3.PutBucketAsync (PutBucketRequest, CancellationToken)

public virtual Task<PutBucketResponse> PutBucketAsync(
         PutBucketRequest request,
         [CancellationToken cancellationToken]
)

Sample

下記サンプルでは、先に「DoesS3BucketExistV2Async」を利用し、Bucketが存在するかどうかのチェックを行っています。もし存在しない場合は、Bucketを作成するという流れです。

private const string BUCKET_NAME = "samplebucket";

public void CreateS3Bucket()
{
    Task<bool> res = CreateS3BucketAsync();
    if(res.Result == true)
    {
        Console.WriteLine("Succeeded!!");
        return;
    }
    Console.WriteLine("Failed.");
}

private async Task<bool> CreateS3BucketAsync()
{
    try
    {
        bool isExisted = await AmazonS3Util.DoesS3BucketExistV2Async(m_client, BUCKET_NAME);
        if(isExisted == false)
        {
            PutBucketRequest request = new PutBucketRequest { BucketName = BUCKET_NAME, UseClientRegion = true };
            PutBucketResponse res = await m_client.PutBucketAsync(request);
            if(res != null)
            {
                return true;
            }
        }
    }
    catch(Exception e)
    {
        Console.WriteLine(e.Message);
    }
    return false;
}

ファイルのアップロード

先ほど作成したS3Bucketにファイルをアップロードします。
アップロード方法はいくつかありますが、今回は、「UploadObjectFromFilePathAsync」を利用したいと思います。

Syntax

ICoreAmazonS3.UploadObjectFromFilePathAsync (string, string, string, IDictionary<String, Object>, CancellationToken)

public abstract Task UploadObjectFromFilePathAsync(
         String bucketName,
         String objectKey,
         String filepath,
         IDictionary<String, Object> additionalProperties,
         CancellationToken cancellationToken
)

Sample

private const string BUCKET_NAME = "samplebucket";
private const string KEY_NAME = "sampleKey/sample.txt";
private const string FILE_PATH = @"C:\Sample\sample.txt";

public void UploadS3Buckect()
{
    UploadS3BucketAsync().Wait();
}

private async Task UploadS3BucketAsync()
{
    try
    {
        bool isExisted = await AmazonS3Util.DoesS3BucketExistV2Async(m_client, BUCKET_NAME);
        if (isExisted == true)
        {
            await m_client.UploadObjectFromFilePathAsync(BUCKET_NAME, KEY_NAME, FILE_PATH, null);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

アップロード方法のサンプルとして、下記でも紹介されていますので参考までに。

AWS SDK for .NET を使用して S3 バケットにファイルをアップロードする (低レベル API)

アップロードしたファイル情報を確認する

先ほどアップロードしたファイルをC#を利用して確認してみます。

Syntax

IAmazonS3.GetObjectAsync (string, string, CancellationToken)

public abstract Task<GetObjectResponse> GetObjectAsync(
         String bucketName,
         String key,
         CancellationToken cancellationToken
)

Sample

GetObjectResponseとして返り値を取得し、その値を標準出力で出力しています。

詳細は下記を参考にしてください。

GetObjectResponse

private const string BUCKET_NAME = "samplebucket";
private const string KEY_NAME = "sampleKey/sample.txt";

public void GetS3Object()
{
    Task<GetObjectResponse> response = GetS3ObjectAsync();
    if(response.Result != null)
    {
        var result = response.Result;
        Console.WriteLine($"BucketName : {result.BucketName}");
        Console.WriteLine($"Key        : {result.Key}");
    }
    return;
}

private async Task<GetObjectResponse> GetS3ObjectAsync()
{
    try
    {
        GetObjectResponse res = await m_client.GetObjectAsync(BUCKET_NAME, KEY_NAME]);
        return res;
    }
    catch(Exception e)
    {
        Console.WriteLine(e.Message);
    }
    return null;
}

実行した結果は下記となりました。

BucketName : samplebucket
Key        : sampleKey/sample.txt

ファイルダウンロード

アップロードしたファイルをダウンロードします。

ここでは、DownloadToFilePathAsyncメソッドとListObjectsからStreamを利用してファイルをダウンロードする2つの方法をご紹介します。

DownloadToFilePathAsyncを利用したダウンロード

Syntax

ICoreAmazonS3.DownloadToFilePathAsync (string, string, string, IDictionary<String, Object>, CancellationToken)

public abstract Task DownloadToFilePathAsync(
         String bucketName,
         String objectKey,
         String filepath,
         IDictionary<String, Object> additionalProperties,
         CancellationToken cancellationToken
)

Sample

private const string BUCKET_NAME = "samplebucket";
private const string KEY_NAME = "sampleKey/sample.txt";
private const string LOCATION_PATH = @"C:\Sample\sample.txt";

public void DownloadS3Buckect()
{
    DownloadS3BucketAsync().Wait();
}

private async Task DownloadS3BucketAsync()
{
    try
    {
        bool isExisted = await AmazonS3Util.DoesS3BucketExistV2Async(m_client, BUCKET_NAME);
        if (isExisted == true)
        {
            await m_client.DownloadToFilePathAsync(BUCKET_NAME, KEY_NAME, LOCATION_PATH, null);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

上記実行後、LOCATION_PATHにsmaple.txtファイルがダウンロードされます。

ListObjectsでStreamを利用する

Syntax

AmazonS3Client.ListObjects (ListObjectsRequest)

public virtual ListObjectsResponse ListObjects(
         ListObjectsRequest request
)

Sample

下記サンプルは、対象キープレフィックス配下にあるファイルすべてをダウンロードします。

DownloadToFilePathAsyncでは、ファイルに対して操作を行いますが、下記はディレクトリ単位で操作を行う方法となります。

ListObjectsRequest req = new ListObjectsRequest();
req.BucketName = "samplebucket";
req.Prefix = "sampleKey";

ListObjectsResponse res = m_client.ListObjects(req);

if(res != null) {
    foreach(S3Object target in res.S3Objects) {
        GetObjectRequest req1 = new GetObjectRequest();
        req1.BucketName = "samplebucket";
        req1.Key = target.Key;

        if(target.Size > 0) {
            using(Stream resStream = Response.ResponseStream) {
                Response.WriteResponseStreamToFile(Path.Combine("C:¥Smaple¥", target.Key))   
            }
        }

    }
}

ファイルの削除

アップロードしたファイルをS3から削除します。

Syntax

AmazonS3Client.DeleteObjectAsync (DeleteObjectRequest, CancellationToken)

public virtual Task<DeleteObjectResponse> DeleteObjectAsync(
         DeleteObjectRequest request,
         CancellationToken cancellationToken
)

Sample

DeleteObjectRequestを作成して、引数に渡してあげます。

private const string BUCKET_NAME = "samplebucket";
private const string KEY_NAME = "sampleKey/sample.txt";

public void DeleteS3Object()
{
    DeleteS3ObjectAsync().Wait();
}

private async Task DeleteS3ObjectAsync()
{
    try
    {
        DeleteObjectRequest req = new DeleteObjectRequest { BucketName = BUCKET_NAME, Key = KEY_NAME };

        await m_client.DeleteObjectAsync(req);
    }
    catch(Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

上記実行後、削除されています。

最後に

PowerShellでのS3操作に引き続き C#でのS3操作についてまとめてみました。

他にもいろいろやり方はありますが、基本的には上記でほぼ対応できてしまうかと思います。

他にもJavaなどでも同じことができますが、Javaについてはまた時間がある時にでもまとめてみたいと思います。