首页 > 解决方案 > 如何使用带有 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-platformgoogle-cloud-storage

解决方案


来自 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;
    }
}

推荐阅读