演習 - BLOB のアップロードとダウンロード

完了

Blob Storage 内の個別の BLOB を操作するには、BlobClient オブジェクトを使います。 BlobClient を取得するには、BLOB が存在する BlobContainerClient に BLOB の名前でそれを要求します。 BlobClient には、Blob Storage 内の個々の BLOB をアップロード、ダウンロード、管理するメソッドがあります。

BlobClient オブジェクトの取得

BlobClient を名前で取得するには、BLOB が含まれる BlobContainerClient で、BLOB の名前を使用して GetBlobClient メソッドを呼び出します。 BlobClient オブジェクトを使うと、BLOB と対話し、Blob Storage 内の BLOB のアップロード、ダウンロード、管理を行うことができます。

BLOB 間のデータ移動は、時間がかかるネットワーク操作です。 Azure Storage SDK for .NET には、ネットワーク アクティビティを必要とするすべてのメソッドの非同期実装が用意されています。 アプリケーションでは、可能な限り、これらの非同期実装を使うことをお勧めします。

大規模なデータ オブジェクトを操作する場合は、バイト配列や文字列などのメモリ内の構造ではなくストリームを使用することをお勧めします。 このアプローチにより、ターゲットへの送信前に、すべての内容がメモリ内にバッファリングされるのを回避できます。 ASP.NET Core では、要求と応答でのストリームの読み取りおよび書き込みがサポートされています。

BlobClient を名前で取得するには、BLOB が含まれる BlobContainerClient で、BLOB の名前を使用して getBlobClient メソッドを呼び出します。 BlobClient オブジェクトを使うと、BLOB と対話し、Blob Storage 内の BLOB のアップロード、ダウンロード、管理を行うことができます。

大規模なデータ オブジェクトを操作する場合は、バイト配列や文字列などのメモリ内の構造ではなくストリームを使用することをお勧めします。 このアプローチにより、ターゲットへの送信前に、すべての内容がメモリ内にバッファリングされるのを回避できます。

新しい BLOB を作成する

新しい BLOB を作成するには、ストレージ内に存在していない BLOB に対して、参照にある Upload メソッドのいずれかを呼び出します。 このアプローチにより、ストレージ内での BLOB の作成とデータのアップロードという 2 つのことが行われます。

BlobClient blobClient = containerClient.GetBlobClient(name);

var response = blobClient.UploadAsync(fileStream);

新しい BLOB を作成するには、ストレージ内に存在していない BLOB に対して、参照にある upload メソッドのいずれかを呼び出します。 このアプローチにより、ストレージ内での BLOB の作成とデータのアップロードという 2 つのことが行われます。

BlobClient blobClient = blobContainerClient.getBlobClient(name);
blobClient.upload(inputStream, contentLength);

演習

アップロードおよびダウンロードのコードを追加してアプリを完成させてから、テストのためにそれを Azure App Service にデプロイします。

アップロード

BLOB をアップロードするには、BlobStorage.Save メソッドを実装します。 最初に、BlobContainerClientGetBlobClient を呼び出すことによって、BLOB を表す BlobClient オブジェクトを取得します。 次に、BlobClientUploadAsync メソッドを使って、このメソッドに渡されたデータの Stream を Blob Storage に保存します。

  • エディターで、BlobStorage.csSave を次のコードに置き換えます。 Ctrl+S キーを使用して作業内容を保存します。

    public Task Save(Stream fileStream, string name)
    {
        BlobServiceClient blobServiceClient = new BlobServiceClient(storageConfig.ConnectionString);
    
        // Get the container (folder) the file will be saved in
        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(storageConfig.FileContainerName);
    
        // Get the Blob Client used to interact with (including create) the blob
        BlobClient blobClient = containerClient.GetBlobClient(name);
    
        // Upload the blob
        return blobClient.UploadAsync(fileStream);
    }
    

    Note

    ここに示したストリーム ベースのアップロード コードは、バイト配列にファイルを読み込んでから Blob Storage に送信するより効率的です。 ただし、クライアントからファイルを取得するために使用する ASP.NET Core IFormFile 手法は、真のエンドツーエンド ストリーミング実装ではありません。 これが適しているのは、小さいファイルのアップロードを処理する場合のみです。

BLOB をアップロードするには、BlobStorage.save メソッドを実装します。 最初に、BlobContainerClientgetBlobClient を呼び出すことによって、BLOB を表す BlobClient オブジェクトを取得します。 次に、BlobClientupload メソッドを使って、このメソッドに渡されたデータの InputStream を Blob Storage に保存します。

  • エディターで、BlobStorage.javasave を次のコードに置き換えます。

    public void save(String name, InputStream inputStream, long contentLength) {
        BlobClient blobClient = blobContainerClient.getBlobClient(name);
        blobClient.upload(inputStream, contentLength);
    }
    

ダウンロード

ファイルをダウンロードするには、BlobClient オブジェクトの OpenReadAsync メソッドが返されます。 このメソッドは Stream を返します。これは、コードが Blob Storage から一度にすべてのバイトを読み込む必要がないことを意味します。 必要なのは、BLOB ストリームへの参照を返すことだけです。ASP.NET Core はそれを使って、ブラウザーにコンテンツをストリーミングできます。

  • Load をこのコードに置き換え、Ctrl + S キーを使用して作業内容を保存します。

    public Task<Stream> Load(string name)
    {
        BlobServiceClient blobServiceClient = new BlobServiceClient(storageConfig.ConnectionString);
    
        // Get the container the blobs are saved in
        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(storageConfig.FileContainerName);
    
        // Get a client to operate on the blob so we can read it.
        BlobClient blobClient = containerClient.GetBlobClient(name);
    
        return blobClient.OpenReadAsync();
    }
    

ファイルをダウンロードするには、BlobClientopenInputStream メソッドを使用します。 このメソッドは InputStream を返します。これは、コードが Blob Storage から一度にすべてのバイトを読み込む必要がないことを意味します。 必要なのは、BLOB ストリームへの参照を返すことだけです。IndexBean はそれを使って、ブラウザーにコンテンツをストリーミングできます。

read をこのコードに置き換えて、作業内容を保存します。

public InputStream read(String name) {
    BlobClient blobClient = blobContainerClient.getBlobClient(name);
    return blobClient.openInputStream();
}

Azure 内でデプロイして実行する

アプリが完成しました。 デプロイして動作を確認します。

  1. App Service アプリを作成し、今回のストレージ アカウント接続文字列とコンテナー名をアプリ設定に指定してアプリを構成します。 az storage account show-connection-string を使用してストレージ アカウントの接続文字列を取得し、コンテナーの名前が files になるように設定します。

    アプリ名はグローバルに一意である必要があります。 <your-unique-app-name> に入力する独自の名前を選択します。 以前に作成したストレージ アカウント名を使用して <your-unique-storage-account-name> を置き換えます。 Azure CLI で、次の各コマンドをこの順に実行します。

    az appservice plan create \
    --name blob-exercise-plan \
    --resource-group "<rgn>[sandbox resource group name]</rgn>" \
    --sku FREE --location eastus
    
    az webapp create \
    --name <your-unique-app-name> \
    --plan blob-exercise-plan \
    --resource-group "<rgn>[sandbox resource group name]</rgn>"
    
    CONNECTIONSTRING=$(az storage account show-connection-string \
    --name <your-unique-storage-account-name> \
    --resource-group "<rgn>[sandbox resource group name]</rgn>" \
    --output tsv)
    
    az webapp config appsettings set \
    --name <your-unique-app-name> --resource-group "<rgn>[sandbox resource group name]</rgn>" \
    --settings AzureStorageConfig:ConnectionString=$CONNECTIONSTRING AzureStorageConfig:FileContainerName=files
    
  2. アプリを展開します。 次のコマンドによってサイトを pub フォルダーに発行し、site.zip として圧縮した後、その zip を App Service にデプロイします。

    Note

    シェルがまだ mslearn-store-data-in-azure/store-app-data-with-azure-blob-storage/src/start ディレクトリにあることを確認してから、次のコマンドを実行します。 この場所にディレクトリを変更するには、cd mslearn-store-data-in-azure/store-app-data-with-azure-blob-storage/src/start を使用します。

    dotnet publish -o pub
    cd pub
    zip -r ../site.zip *
    
    az webapp deployment source config-zip \
    --src ../site.zip \
    --name <your-unique-app-name> \
    --resource-group "<rgn>[sandbox resource group name]</rgn>"
    

    実行中のアプリを表示するには、ブラウザーで https://<your-unique-app-name>.azurewebsites.net を開きます。 それは次の図のようになるはずです。

    Screenshot of the FileUploader web app for C#.

  3. アプリをテストするため、ファイルをいくつかアップロードしてダウンロードしてみましょう。 いくつかのファイルをアップロードした後、コンテナー内の BLOB を表示するには、シェルで次のコードを実行します。 <your-unique-storage-account-name> を、このモジュールの前半で作成したストレージ アカウント名に置き換えます。

    az storage blob list --account-name <your-unique-storage-account-name> --container-name files --query [].{Name:name} --output table
    

アプリが完成しました。 デプロイして動作を確認します。 Azure App Service 用の Maven プラグインを使用して、App Service アプリを作成し、構成してデプロイします。

  1. エディターでファイル pom.xml を開き、次の pluginsbuild xml タグの下に追加します。

    <plugins>
       <plugin>
         <groupId>com.microsoft.azure</groupId>
         <artifactId>azure-webapp-maven-plugin</artifactId>
         <version>2.3.0</version>
         <configuration>
           <schemaVersion>v2</schemaVersion>
           <subscriptionId>${env.AZ_SUBSCRIPTION_ID}</subscriptionId>
           <resourceGroup>${env.AZ_RESOURCE_GROUP}</resourceGroup>
           <appName>${env.AZ_APP_NAME}</appName>
           <pricingTier>${env.AZ_PRICING_TIER}</pricingTier>
           <region>${env.AZ_REGION}</region>
           <runtime>
             <os>Linux</os>
             <javaVersion>Java 11</javaVersion>
             <webContainer>Tomcat 9.0</webContainer>
           </runtime>
           <deployment>
             <resources>
               <resource>
                 <directory>${project.basedir}/target</directory>
                 <includes>
                   <include>*.war</include>
                 </includes>
               </resource>
             </resources>
           </deployment>
                 <appSettings>
                   <property>
                      <name>STORAGE_CONNECTION_STRING</name>
                      <value>${env.AZ_STORAGE_CONNECTION_STRING}</value>
                   </property>
                   <property>
                      <name>STORAGE_CONTAINER_NAME</name>
                      <value>${env.AZ_STORAGE_CONTAINER_NAME}</value>
                   </property>
                </appSettings>
         </configuration>
       </plugin>
       <plugin>  
         <groupId>org.apache.maven.plugins</groupId>  
         <artifactId>maven-war-plugin</artifactId>  
         <version>3.3.2</version>  
       </plugin> 
     </plugins>
    
  2. 次のコマンドを使用して、Azure App Service 用 Maven プラグインの環境変数を準備します。 ストレージ アカウントの接続文字列を az storage account show-connection-string で、サブスクリプション ID を az account show で抽出し、リージョン、価格、コンテナー名、アプリ名を設定します。 アプリ名はグローバルに一意である必要があります。 <your-unique-app-name> に入力する独自の名前を選択します。

    export AZ_SUBSCRIPTION_ID=$(az account show --query id --output tsv)
    export AZ_RESOURCE_GROUP="<rgn>[sandbox resource group name]</rgn>"
    export AZ_REGION=eastus
    export AZ_APP_NAME=<your-unique-app-name>
    export AZ_PRICING_TIER=F1
    export AZ_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string --name <your-unique-storage-account-name> --output tsv)
    export AZ_STORAGE_CONTAINER_NAME=files
    

    ヒント

    実際の Java アプリケーションをデプロイするための最小推奨レベルは、Premium V2 サービス プランです。

  3. アプリを展開します。 次のコマンドを使用してアプリを ROOT.war にビルドし、WAR ファイルを App Service にデプロイします。 Azure App Service 用 Maven プラグインによって、最初のデプロイ試行時にリソースがプロビジョニングされます。

    Note

    シェルがまだ mslearn-store-data-in-azure/store-java-ee-application-data-with-azure-blob-storage/start ディレクトリにあることを確認してから、次のコマンドを実行します。 この場所にディレクトリを変更するには、cd mslearn-store-data-in-azure/store-java-ee-application-data-with-azure-blob-storage/start を使用します。

    mvn clean package azure-webapp:deploy
    

    実行中のアプリを表示するには、ブラウザーで https://<your-unique-app-name>.azurewebsites.net を開きます。 それは次の図のようになるはずです。

    Screenshot of the FileUploader web app for Java.

    ヒント

    このモジュールでは、Azure App Service 用の Maven プラグインを使用して、Azure App Service 上の Tomcat 9 にアプリをデプロイします。 その他のオプションについては、このモジュールの最後にある「参考資料」セクションを参照してください。

  4. アプリをテストするため、ファイルをいくつかアップロードしてダウンロードしてみましょう。 いくつかのファイルをアップロードした後、コンテナー内の BLOB を表示するには、シェルで次のコードを実行します。

    az storage blob list --account-name <your-unique-storage-account-name> --container-name files --query [].{Name:name} --output table