Google Cloud Storageからファイルをダウンロードするコードは次のとおりです。
@Override
public void write(OutputStream outputStream) throws IOException {
try {
LOG.info(path);
InputStream stream = new ByteArrayInputStream(GoogleJsonKey.JSON_KEY.getBytes(StandardCharsets.UTF_8));
StorageOptions options = StorageOptions.newBuilder()
.setProjectId(PROJECT_ID)
.setCredentials(GoogleCredentials.fromStream(stream)).build();
Storage storage = options.getService();
final CountingOutputStream countingOutputStream = new CountingOutputStream(outputStream);
byte[] read = storage.readAllBytes(BlobId.of(BUCKET, path));
countingOutputStream.write(read);
} catch (Exception e) {
e.printStackTrace();
} finally {
outputStream.close();
}
}
これは機能しますが、ここでの問題は、このメソッドのクライアントにストリームバックする前に、最初にすべてのバイトをバッファする必要があることです。これにより、特にGCSに保存されているファイルが大きい場合、多くの遅延が発生します。
GCSからファイルを取得し、それを直接OutputStreamにストリーミングする方法はありますが、このOutputStreamはサーブレット用です。
ただ、明確にするために、あなたが必要なのですOutputStream
かInputStream
?これを見る1つの方法は、Google Cloud Storageオブジェクトにファイルとして保存されているデータと、そのファイルを読み取るためのInputStreamを持っていることです。それがうまくいくなら、読み続けてください。
Storage APIには、InputStream
またはを提供する既存のメソッドはありませんOutputStream
。ただし、Cloud StorageクライアントライブラリReadChannel
には、ReadableByteChannel
(Java NIO APIから)拡張されたオブジェクトを公開する2つのAPIがあります。
ReadChannel reader(String bucket, String blob, BlobSourceOption... options);
ReadChannel reader(BlobId blob, BlobSourceOption... options);
これを使用した簡単な例(StorageSnippets.javaから取得):
/**
* Example of reading a blob's content through a reader.
*/
// [TARGET reader(String, String, BlobSourceOption...)]
// [VARIABLE "my_unique_bucket"]
// [VARIABLE "my_blob_name"]
public void readerFromStrings(String bucketName, String blobName) throws IOException {
// [START readerFromStrings]
try (ReadChannel reader = storage.reader(bucketName, blobName)) {
ByteBuffer bytes = ByteBuffer.allocate(64 * 1024);
while (reader.read(bytes) > 0) {
bytes.flip();
// do something with bytes
bytes.clear();
}
}
// [END readerFromStrings]
}
また、使用することができますnewInputStream()
ラップするメソッドをInputStream
介してReadableByteChannel
。
public static InputStream newInputStream(ReadableByteChannel ch)
が必要な場合でも、オブジェクトOutputStream
から、InputStream
またはReadChannel
オブジェクトからにデータをコピーできるはずOutputStream
です。
この例を次のように実行します。 PROGRAM_NAME <BUCKET_NAME> <BLOB_PATH>
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import com.google.cloud.ReadChannel;
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.BucketInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
/**
* An example which reads the contents of the specified object/blob from GCS
* and prints the contents to STDOUT.
*
* Run it as PROGRAM_NAME <BUCKET_NAME> <BLOB_PATH>
*/
public class ReadObjectSample {
private static final int BUFFER_SIZE = 64 * 1024;
public static void main(String[] args) throws IOException {
// Instantiates a Storage client
Storage storage = StorageOptions.getDefaultInstance().getService();
// The name for the GCS bucket
String bucketName = args[0];
// The path of the blob (i.e. GCS object) within the GCS bucket.
String blobPath = args[1];
printBlob(storage, bucketName, blobPath);
}
// Reads from the specified blob present in the GCS bucket and prints the contents to STDOUT.
private static void printBlob(Storage storage, String bucketName, String blobPath) throws IOException {
try (ReadChannel reader = storage.reader(bucketName, blobPath)) {
WritableByteChannel outChannel = Channels.newChannel(System.out);
ByteBuffer bytes = ByteBuffer.allocate(BUFFER_SIZE);
while (reader.read(bytes) > 0) {
bytes.flip();
outChannel.write(bytes);
bytes.clear();
}
}
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加