googleが提供するJavaライブラリcom.google.cloud.storageを使用してGoogle Cloud Storageから大きなファイルをダウンロードします。私は作業コードを持っていますが、まだ1つの質問と1つの大きな懸念があります:チェックサムコントロール付きJavaを使用してGoogle Cloud Storageから大きなファイルをダウンロードする方法
私の主な関心事は、ファイルの内容が実際にダウンロードされるのはいつですか?中に(の)、blob.reader()
の間またはreader.read(bytes)
の間に(下のコードへの参照)?これは非常に重要です。無効なチェックサムを処理するには、ファイルがネットワーク経由で再度フェッチされるように実際にトリガーする必要がありますか?
もっと簡単な質問は次のとおりです。受信したファイルをGoogleライブラリでmd5(またはcrc32c)チェックする機能は組み込まれていますか?たぶん私は自分でそれを実装する必要はありません。ここで
は、Googleのクラウドストレージから大きなファイルをダウンロードしようとしている私の方法です:
private static final int MAX_NUMBER_OF_TRIES = 3;
public Path downloadFile(String storageFileName, String bucketName) throws IOException {
// In my real code, this is a field populated in the constructor.
Storage storage = Objects.requireNonNull(StorageOptions.getDefaultInstance().getService());
BlobId blobId = BlobId.of(bucketName, storageFileName);
Path outputFile = Paths.get(storageFileName.replaceAll("/", "-"));
int retryCounter = 1;
Blob blob;
boolean checksumOk;
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
do {
LOGGER.debug("Start download file {} from bucket {} to Content Store (try {})", storageFileName, bucketName, retryCounter);
blob = storage.get(blobId);
if (null == blob) {
throw new CloudStorageCommunicationException("Failed to download file after " + retryCounter + " tries.");
}
if (Files.exists(outputFile)) {
Files.delete(outputFile);
}
try (ReadChannel reader = blob.reader();
FileChannel channel = new FileOutputStream(outputFile.toFile(), true).getChannel()) {
ByteBuffer bytes = ByteBuffer.allocate(128 * 1024);
int bytesRead = reader.read(bytes);
while (bytesRead > 0) {
bytes.flip();
messageDigest.update(bytes.array(), 0, bytesRead);
channel.write(bytes);
bytes.clear();
bytesRead = reader.read(bytes);
}
}
String checksum = Base64.encodeBase64String(messageDigest.digest());
checksumOk = checksum.equals(blob.getMd5());
if (!checksumOk) {
Files.delete(outputFile);
messageDigest.reset();
}
} while (++retryCounter <= MAX_NUMBER_OF_TRIES && !checksumOk);
if (!checksumOk) {
throw new CloudStorageCommunicationException("Failed to download file after " + MAX_NUMBER_OF_TRIES + " tries.");
}
return outputFile;
}
意味があります!無効なチェックサムを検出した場合は、com.google.cloud.storageライブラリにファイルを再度ダウンロードし、キャッシュからフェッチしないように強制する方法がありますか? –
私は気にしません。無効なチェックサムを取得した場合、そのエラーはネットワーク上の問題である可能性が高く、2回目には発生しません。また、特に奇妙な企業のファイアウォールの背後にいなければ、資格情報で行われたHTTPS読み取りはほとんど確実にキャッシュされません。それにもかかわらず、 "&skipCaching = 12345"のような特別なナンセンスURLパラメータを追加するだけで、ほとんどのキャッシュをスキップできます。 –
問題はHTTPキャッシュではなく、Googleが提供するJavaライブラリのキャッシュ(上記の質問のリンク)です。 ReadChannelのJavaDocは、「このクラスの実装は、データを内部的にバッファリングしてリモート呼び出しを減らすことができる」と述べています。ここでは、チェックサム検証について説明していますが、私の知る限り質問に答えることはできません。https://cloud.google.com/storage/docs/hashes-etagsしたがって、私はURLを直接残念ながら使用していません。 –