google-cloud-platform - 如何使用带有 WriteChannel 和 MD5 检查的 JAVA 库上传到 Google Storage
问题描述
使用写入写入器通道的输出流时,如何对上传的内容执行 MD5 检查?当我这样做Storage::create
时,提供的 BlobInfo 中的 MD5 会被EMPTY_BYTE_ARRAY_MD5
. 这是有道理的,因为最初创建 blob 时,确实是空的。但我希望编写器上的某些方法可以设置一个更新的 MD5,一旦编写器关闭,它就应该是有效的。我找不到实现此目的的方法,这可能吗?我将附上我的代码:
摇篮:
api 'com.google.cloud:google-cloud-storage:1.51.0'
Java代码:
import com.google.cloud.WriteChannel;
import com.google.cloud.storage.*;
import com.google.common.io.ByteStreams;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
import java.nio.file.Path;
class StorageServiceImpl {
@Inject
private Storage storage;
public BlobInfo uploadFile(final Path localFile, final String bucketName, final String fileName, final String downloadFileName) throws IOException {
Blob blob = null;
String checksum = md5(localFile);
try (InputStream inputStream = new FileInputStream(localFile.toFile())) {
blob = storage.create(
BlobInfo.newBuilder(bucketName, fileName)
.setContentType("application/octet-stream")
.setContentDisposition(String.format("attachment; filename=\"%s\"", downloadFileName))
.setMd5(checksum)
.build()
);
try (WriteChannel writer = blob.writer(Storage.BlobWriteOption.md5Match())) {
ByteStreams.copy(inputStream, Channels.newOutputStream(writer));
}
} catch (StorageException ex) {
if (!(400 == ex.getCode() && "invalid".equals(ex.getReason()))) {
throw ex;
}
}
return blob;
}
}
一旦我们从不推荐使用的方法迁移,就会出现这个问题Blob create(BlobInfo blobInfo, InputStream content, BlobWriteOption... options);
。
解决方案
来自 Google Cloud 支持的答复
不要创建 blob 并请求 blob 的写入器。相反,请求存储的写入器并向该请求提供 blob 信息。
import com.google.cloud.WriteChannel;
import com.google.cloud.storage.*;
import com.google.common.io.ByteStreams;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
import java.nio.file.Path;
class StorageServiceImpl {
@Inject
private Storage storage;
public BlobInfo uploadFile(final Path localFile, final String bucketName, final String fileName, final String downloadFileName) throws IOException {
BlobInfo blobInfo = null;
String checksum = md5(localFile);
try (InputStream inputStream = new FileInputStream(localFile.toFile())) {
blobInfo =
BlobInfo.newBuilder(bucketName, fileName)
.setContentType("application/octet-stream")
.setContentDisposition(String.format("attachment; filename=\"%s\"", downloadFileName))
.setMd5(checksum)
.build();
try (WriteChannel writer = storage.writer(blobInfo, Storage.BlobWriteOption.md5Match())) {
ByteStreams.copy(inputStream, Channels.newOutputStream(writer));
}
} catch (StorageException ex) {
if (!(400 == ex.getCode() && "invalid".equals(ex.getReason()))) {
throw ex;
}
}
return blobInfo;
}
}
推荐阅读
- python-3.x - 为什么变量(第 6 行)有一个白色的空格?(Nivel: 初级工作流程符石)
- python - 在python中通过引用传递
- autohotkey - 使用 ControlClick 和 WinTitle 的问题
- wordpress - wordpress 在将文本显示给浏览器之前替换文本
- cypress - 赛普拉斯:如果未找到来自“cy.route()”的请求,则测试失败
- javascript - 角反应形式日期设定值
- flutter - 在 Flutter 中,如何使用 WebView 制作简单的浏览器小部件?
- r - 将大型数据集从长转换为宽(450 多个值变量)
- rdf - Semantic Web - Turtle 和 JSON-LD 是一回事吗 - 一种保存 RDF 的方法
- python - Python math.log 函数数学域错误