从Google Cloud Storage流式传输文件

夸克:

这是从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是用于Servlet的。

固定:

只是为了澄清,您需要一个OutputStream还是一个InputStream一种查看方式是,将Google Cloud Storage对象中存储的数据作为文件存储,并且您有一个InputStream可以读取该文件。如果可行,请继续阅读。

Storage API中没有提供InputStream或的现有方法OutputStream但是Cloud Storage客户端库中2个API,它们公开了一个ReadChannel对象ReadableByteChannel(从Java NIO 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()方法来包装一个InputStreamReadableByteChannel

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

通过Node / Express服务器将大文件(2GB +)流式传输到Google Cloud Storage存储桶

将大文件从Google BigQuery传输到Google Cloud Storage

使用Cloud Functions将文件从Google Cloud Storage传输到Windows VM实例

使用Tornado将二进制文件流式传输到Google Storage

以编程方式将文件从Azure Blob存储传输到Google Cloud Storage

使用Google Cloud Dataflow合并Google Cloud Storage中的文件

Google Cloud Storage与Google Cloud CDN

数据存储区管理员:备份到Google Cloud Storage-未传输的文件系统,为什么?

Google Cloud Storage加入多个csv文件

如何从Google Cloud Storage解密文件?

Google Cloud Storage中的Concat Avro文件

使用Google DataFlow对直接将数据流式传输到Cloud SQL的简单查询

将文件从 URL 传输到 Cloud Storage

Cloud ML无法在Google Cloud Storage上找到文件

如何从Google App Engine读取Google Cloud Storage文件

从Cloud Function(Python)写入Google Cloud Storage

在Google Cloud中流式插入/更新-BigQuery

Google Cloud Storage ACL混淆

Google Cloud Storage Force下载

PHP 的 Google Cloud Storage 问题

Google Cloud Storage - 权限不足

删除Google Cloud Storage文件夹下的所有文件

使用Google Cloud Console在Google Cloud Storage中的文件夹之间移动文件

如何通过socket.io将实时音频从浏览器流式传输到Google Cloud Speech?

如何从Google Cloud Functions NodeJS连接到Google Cloud Storage

在 Google Cloud Build 中使用 Google Cloud Storage

使用Google Cloud Storage代替Google Cloud SQL保存文件有什么好处

如何通过 Pandas 从 Google Cloud Function 中的 Google Cloud Storage 访问 csv 文件?

从两个不同的Google Cloud项目访问Google Cloud Storage中的文件