使用 Java 上传块 Blob
本文介绍如何使用适用于 Java 的 Azure 存储客户端库上传块 blob。 可以通过文件路径、流、二进制对象或文本字符串将数据上传到块 Blob。 还可以上传带有索引标记的 Blob。
先决条件
- Azure 订阅 - 创建试用订阅。
- Azure 存储帐户 - 创建存储帐户
- Java 开发工具包 (JDK) 8 或更高版本(我们建议使用版本 17 以获得最佳体验)
- 在本示例中,Apache Maven 用于项目管理
设置你的环境
如果没有现有项目,请查看本部分,其中介绍了如何设置项目来使用适用于 Java 的 Azure Blob 存储客户端库。 有关详细信息,请参阅 Azure Blob 存储和 Java 入门。
要使用本文中的代码示例,请按照以下步骤设置项目。
注意
本文使用 Maven 生成工具来生成和运行示例代码。 其他生成工具(例如 Gradle)也可与 Azure SDK for Java 一起使用。
安装包
在文本编辑器中打开 pom.xml
文件。 通过包括 BOM 文件或包括直接依赖项来安装包。
添加 import 语句
添加以下 import
语句:
import com.azure.core.http.rest.*;
import com.azure.core.util.BinaryData;
import com.azure.storage.blob.*;
import com.azure.storage.blob.models.*;
import com.azure.storage.blob.options.BlobUploadFromFileOptions;
import com.azure.storage.blob.specialized.*;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.time.Duration;
import java.util.*;
授权
授权机制必须具有上传 blob 所需的权限。 若要使用 Microsoft Entra ID 进行授权(建议),需要 Azure RBAC 内置角色“存储 Blob 数据参与者”或更高级别的角色。 若要了解详细信息,请参阅有关放置 Blob (REST API) 和放置块 (REST API) 的授权指南。
创建客户端对象
若要将应用连接到 Blob 存储,请创建 BlobServiceClient 的实例。
以下示例使用 BlobServiceClientBuilder 生成一个使用 DefaultAzureCredential
的 BlobServiceClient
对象,并演示如何创建容器和 Blob 客户端(如果需要):
// Azure SDK client builders accept the credential as a parameter
// TODO: Replace <storage-account-name> with your actual storage account name
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
.endpoint("https://<storage-account-name>.blob.core.chinacloudapi.cn/")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
// If needed, you can create a BlobContainerClient object from the BlobServiceClient
BlobContainerClient containerClient = blobServiceClient
.getBlobContainerClient("<container-name>");
// If needed, you can create a BlobClient object from the BlobContainerClient
BlobClient blobClient = containerClient
.getBlobClient("<blob-name>");
要详细了解如何创建和管理客户端对象,请参阅 创建和管理与数据资源交互的客户端对象。
将数据上传到块 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 的访问层设置为 Hot
、Cool
、Cold
或 Archive
。 若要将访问层设置为 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 操作:
客户端库资源
请参阅
相关内容
- 本文是适用于 Java 的 Blob 存储开发人员指南的一部分。 若要了解详细信息,请参阅生成 Java 应用中的开发人员指南文章的完整列表。