练习 - blob 上传和下载

已完成

若要与 Blob 存储中的单个 blob 交互,请使用 BlobClient 对象。 通过使用 blob 所在的 BlobContainerClient 中的 blob 名称对其进行请求,可以获得一个 BlobClientBlobClient 具有上传、下载和管理 Blob 存储中单个 blob 的方法。

获取 BlobClient 对象

若要按名称获取 BlobClient,请使用 blob 的名称在包含 blob 的 BlobContainerClient 上调用 GetBlobClient 方法。 使用 BlobClient 对象可以通过上传、下载或管理 blob 存储中的 blob 来与 blob 交互。

将数据移入和移出 Blob 是一种需要一定时间的网络操作。 适用于 .NET 的 Azure 存储 SDK 提供需要网络活动的所有方法的异步实现。 建议在应用程序中尽可能使用这些异步实现。

建议在使用大型数据对象时,使用流而不是内存中结构(如字节数组或字符串)。 这种方法可避免在将完整内容发送到目标之前在内存中缓冲这些内容。 ASP.NET Core 支持从请求和响应中读取和写入流。

若要按名称获取 BlobClient,请使用 blob 的名称在包含 blob 的 BlobContainerClient 上调用 getBlobClient 方法。 使用 BlobClient 对象可以通过上传、下载或管理 blob 存储中的 blob 来与 blob 交互。

建议在使用大型数据对象时,使用流而不是内存中结构(如字节数组或字符串)。 这种方法可避免在将完整内容发送到目标之前在内存中缓冲这些内容。

创建新的 blob

若要创建新的 Blob,请在存储中不存在的 blob 引用上调用某种 Upload 方法。 这种方法将执行两项操作:在存储中创建 Blob 并上传数据。

BlobClient blobClient = containerClient.GetBlobClient(name);

var response = blobClient.UploadAsync(fileStream);

若要创建新的 Blob,请在存储中不存在的 blob 引用上调用某种 upload 方法。 这种方法将执行两项操作:在存储中创建 Blob 并上传数据。

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

练习

通过添加上传和下载代码完成应用,然后将该应用部署到 Azure 应用服务进行测试。

上传

若要上传 Blob,请实现 BlobStorage.Save 方法。 首先,通过在 BlobContainerClient 上调用 GetBlobClient 来获得一个表示 Blob 的 BlobClient 对象。 然后,使用 BlobClient 上的 UploadAsync 方法将传递给此方法的数据的 Stream 保存到 Blob 存储。

  • 在编辑器中,在 BlobStorage.cs 中,将 Save 替换为以下代码。 按 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);
    }
    

    注意

    此处所示的基于流的上传代码比将文件读取为字节数组,然后再将其发送到 Blob 存储更高效。 但是,用于从客户端获取文件的 ASP.NET Core IFormFile 技术不是真正的端到端流式处理实现。 它仅适用于处理小型文件的上传。

若要上传 Blob,请实现 BlobStorage.save 方法。 首先,通过在 BlobContainerClient 上调用 getBlobClient 来获得一个表示 Blob 的 BlobClient 对象。 然后,使用 BlobClient 上的 upload 方法将传递给此方法的数据的 InputStream 保存到 Blob 存储。

  • 在编辑器中,在 BlobStorage.java 中,将 save 替换为以下代码。

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

下载

若要下载文件,将返回 BlobClient 对象上的 OpenReadAsync 方法。 此方法返回 Stream,这意味着代码不需要一次性从 Blob 存储加载所有字节。 只需返回对 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();
    }
    

要下载文件,请在 BlobClient 上使用 openInputStream 方法。 此方法返回 InputStream,这意味着代码不需要一次性从 Blob 存储加载所有字节。 只需返回对 Blob 流的引用,IndexBean 可以使用该引用将内容流式传输到浏览器。

使用此代码替换 read 并保存你的工作。

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

在 Azure 中部署和运行

应用已完成。 部署该应用并查看其工作状态。

  1. 创建应用服务应用并使用存储帐户连接字符串和容器名称的应用设置对其进行配置。 使用 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 部署到应用服务。

    注意

    在运行以下命令之前,请确保 shell 仍在 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 deploy \
    --src-path ../site.zip \
    --resource-group "<rgn>[sandbox resource group name]</rgn>" \
    --name <your-unique-app-name>
    

    若要查看正在运行的应用,请在浏览器中打开 https://<your-unique-app-name>.azurewebsites.net。 它应类似于下图。

    适用于 C# 的 FileUploader Web 应用的屏幕截图。

  3. 尝试上传和下载一些文件来测试应用。 上传几个文件后,若要查看容器中的 Blob,请在 shell 中运行以下代码。 将 <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 应用服务的 Maven 插件创建应用服务应用,并对其进行配置和部署。

  1. 在编辑器中打开文件 pom.xml,并将以下 plugins 添加到 build 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 应用服务的 Maven 插件准备环境变量。 使用 az storage account show-connection-string 提取存储帐户的连接字符串、使用 az account show 提取订阅 ID,设置区域、定价、容器名称和应用名称。 应用名称需要全局唯一。 在 <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 应用程序的最低层是任一高级版 V2 服务计划。

  3. 部署应用。 以下命令将应用生成到 ROOT.war,并将 WAR 文件部署到应用服务。 Azure 应用服务的 Maven 插件在首次尝试部署时将预配资源。

    注意

    在运行以下命令之前,请确保 shell 仍在 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。 它应类似于下图。

    适用于 Java 的 FileUploader Web 应用的屏幕截图。

    提示

    本模块使用 Azure 应用服务的 Maven 插件在 Azure 应用服务上的 Tomcat 9 中部署应用。 若要了解其他选项,请参阅本模块末尾的“延伸阅读”部分。

  4. 尝试上传和下载一些文件来测试应用。 上传几个文件后,若要查看容器中的 Blob,请在 shell 中运行以下代码。

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