使用 Java 上传块 Blob

本文介绍如何使用适用于 Java 的 Azure 存储客户端库上传块 blob。 可以通过文件路径、流、二进制对象或文本字符串将数据上传到块 Blob。 还可以上传带有索引标记的 Blob。

先决条件

  • 本文假设已经设置了项目来使用适用于 Java 的 Azure Blob 存储客户端库。 要了解有关设置项目的信息,包括包安装、添加 import 指令和创建授权客户端对象,请参阅开始使用 Azure 存储和 Java
  • 授权机制必须具有执行上传操作的权限。 若要了解详细信息,请参阅以下 REST API 操作的授权指南:

将数据上传到块 Blob

要通过流或二进制对象上传块 Blob,请使用以下方法:

要通过文件路径上传块 Blob,请使用以下方法:

可以使用 BlobClient 对象或 BlockBlobClient 对象调用其中每种方法。

通过本地文件路径上传块 Blob

以下示例使用 BlobClient 对象将文件上传到块 blob:

public void uploadBlobFromFile(BlobContainerClient blobContainerClient) {
    BlobClient blobClient = blobContainerClient.getBlobClient("sampleBlob.txt");

    try {
        blobClient.uploadFromFile("filepath/local-file.png");
    } catch (UncheckedIOException ex) {
        System.err.printf("Failed to upload from file: %s%n", ex.getMessage());
    }
}

通过流式传输上传块 Blob

以下示例通过创建 ByteArrayInputStream 对象,然后上传该流对象来上传块 Blob:

public void uploadBlobFromStream(BlobContainerClient blobContainerClient) {
    BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient("sampleBlob.txt").getBlockBlobClient();
    String sampleData = "Sample data for blob";
    try (ByteArrayInputStream dataStream = new ByteArrayInputStream(sampleData.getBytes())) {
        blockBlobClient.upload(dataStream, sampleData.length());
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

通过 BinaryData 对象上传块 Blob

以下示例使用 BlobClient 对象将 BinaryData 上传到块 Blob:

public void uploadDataToBlob(BlobContainerClient blobContainerClient) {
    // Create a BlobClient object from BlobContainerClient
    BlobClient blobClient = blobContainerClient.getBlobClient("sampleBlob.txt");
    String sampleData = "Sample data for blob";
    blobClient.upload(BinaryData.fromString(sampleData));
}

使用配置选项上传块 blob

上传 blob 时,可以定义客户端库配置选项。 可以优化这些选项以提高性能、增强可靠性和优化成本。 以下代码示例演示如何在调用 upload 方法时使用 BlobUploadFromFileOptions 来定义配置选项。 如果不从文件上传,则可以使用 BlobParallelUploadOptions 对上传方法设置类似的选项。

在上传时指定数据传输选项

可以在 ParallelTransferOptions 中配置值,以提高数据传输操作的性能。 可根据应用需求优化要上传的以下值:

  • blockSize:要为每个请求传输的最大块大小。 可以使用 setBlockSizeLong 方法设置此值。
  • maxSingleUploadSize:如果数据大小小于或等于此值,则会以单个输入上传,不会拆分成多个区块。 如果一次性上传数据,则会忽略块大小。 可以使用 setMaxSingleUploadSizeLong 方法设置此值。
  • maxConcurrency:在任何给定时间,作为单个并行传输的一部分发出的最大并行请求数量。 可以使用 setMaxConcurrency 方法设置此值。

请确保具有以下 import 指令,以便对上传使用 ParallelTransferOptions

import com.azure.storage.blob.models.*;

以下代码示例演示如何设置 ParallelTransferOptions 的值,并将这些选项添加到 BlobUploadFromFileOptions 实例中。 此示例中提供的值不作为建议。 若要正确优化这些值,需要考虑应用的特定需求。

public void uploadBlockBlobWithTransferOptions(BlobContainerClient blobContainerClient, Path filePath) {
    String fileName = filePath.getFileName().toString();
    BlobClient blobClient = blobContainerClient.getBlobClient(fileName);

    ParallelTransferOptions parallelTransferOptions = new ParallelTransferOptions()
            .setBlockSizeLong((long) (4 * 1024 * 1024)) // 4 MiB block size
            .setMaxConcurrency(2)
            .setMaxSingleUploadSizeLong((long) 8 * 1024 * 1024); // 8 MiB max size for single request upload

    BlobUploadFromFileOptions options = new BlobUploadFromFileOptions(filePath.toString());
    options.setParallelTransferOptions(parallelTransferOptions);

    try {
        Response<BlockBlobItem> blockBlob = blobClient.uploadFromFileWithResponse(options, null, null);
    } catch (UncheckedIOException ex) {
        System.err.printf("Failed to upload from file: %s%n", ex.getMessage());
    }
}

若要详细了解如何优化数据传输选项,请参阅优化 Java 的上传和下载性能

上传带有索引标记的块 blob

Blob 索引标记使用键值标记属性对存储帐户中的数据进行分类。 这些标记会自动索引,并作为可搜索的多维索引公开,便于你轻松查找数据。

以下示例使用 BlobUploadFromFileOptions 上传设置了索引标记的块 Blob:

public void uploadBlockBlobWithIndexTags(BlobContainerClient blobContainerClient, Path filePath) {
    String fileName = filePath.getFileName().toString();
    BlobClient blobClient = blobContainerClient.getBlobClient(fileName);

    Map<String, String> tags = new HashMap<String, String>();
    tags.put("Content", "image");
    tags.put("Date", "2022-01-01");

    Duration timeout = Duration.ofSeconds(10);

    BlobUploadFromFileOptions options = new BlobUploadFromFileOptions(filePath.toString());
    options.setTags(tags);

    try {
        // Create a new block blob, or update the content of an existing blob
        Response<BlockBlobItem> blockBlob = blobClient.uploadFromFileWithResponse(options, timeout, null);
    } catch (UncheckedIOException ex) {
        System.err.printf("Failed to upload from file: %s%n", ex.getMessage());
    }
}

在上传期间设置 blob 的访问层

可以使用 BlobUploadFromFileOptions 类在上传时设置 blob 的访问层。 以下代码示例演示如何在上传 blob 时设置访问层:

public void uploadBlobWithAccessTier(BlobContainerClient blobContainerClient, Path filePath) {
    String fileName = filePath.getFileName().toString();
    BlobClient blobClient = blobContainerClient.getBlobClient(fileName);

    BlobUploadFromFileOptions options = new BlobUploadFromFileOptions(filePath.toString())
            .setTier(AccessTier.COOL);

    try {
        Response<BlockBlobItem> blockBlob = blobClient.uploadFromFileWithResponse(options, null, null);
    } catch (UncheckedIOException ex) {
        System.err.printf("Failed to upload from file: %s%n", ex.getMessage());
    }
}

仅允许为块 blob 设置访问层。 可以将块 blob 的访问层设置为 HotCoolColdArchive。 若要将访问层设置为 Cold,必须至少使用客户端库版本 12.21.0。

若要详细了解访问层,请参阅访问层概述

通过暂存块和提交上传块 Blob

可以通过手动暂存单个数据块来更好地控制将上传内容划分为块的方式。 暂存构成 Blob 的所有块后,可以将其提交到 Blob 存储。 可以使用此方法通过并行上传块来提高性能。

public void uploadBlocks(BlobContainerClient blobContainerClient, Path filePath, int blockSize) throws IOException {
    String fileName = filePath.getFileName().toString();
    BlockBlobClient blobClient = blobContainerClient.getBlobClient(fileName).getBlockBlobClient();

    FileInputStream fileStream = new FileInputStream(filePath.toString());
    List<String> blockIDArrayList = new ArrayList<>();
    byte[] buffer = new byte[blockSize];
    int bytesRead;

    while ((bytesRead = fileStream.read(buffer, 0, blockSize)) != -1) {

        try (ByteArrayInputStream stream = new ByteArrayInputStream(buffer)) {
            String blockID = Base64.getEncoder().encodeToString(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));

            blockIDArrayList.add(blockID);
            blobClient.stageBlock(blockID, stream, buffer.length);
        }
    }

    blobClient.commitBlockList(blockIDArrayList);

    fileStream.close();
}

资源

若要详细了解如何使用适用于 Java 的 Azure Blob 存储客户端库来上传 blob,请参阅以下资源。

REST API 操作

Azure SDK for Java 包含基于 Azure REST API 而生成的库,允许你通过熟悉的 Java 范例与 REST API 操作进行交互。 用于上传 blob 的客户端库方法使用以下 REST API 操作:

代码示例

客户端库资源

请参阅