Потоковое содержимое в облачное хранилище Google

#java #google-cloud-storage #nio

#java #google-облачное хранилище #nio

Вопрос:

Я хотел бы загрузить большой Set<Integer> файл в облачное хранилище Google. Я могу сделать это с помощью:

 Blob result = storage.create(blobInfo, Joiner.on('n').join(set).getBytes(UTF_8));
  

Но это создаст промежуточную строку со всем содержимым, которое может быть слишком большим.
Я нашел пример с WriteChannel.write() :

  Set<Integer> set = ...
 String bucketName = "my-unique-bucket";
 String blobName = "my-blob-name";
 BlobId blobId = BlobId.of(bucketName, blobName);
 byte[] content = Joiner.on('n').join(set).getBytes(UTF_8);
 BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("text/plain").build();
 try (WriteChannel writer = storage.writer(blobInfo)) {
     writer.write(ByteBuffer.wrap(content, 0, content.length));
 } catch (IOException ex) {
   // handle exception
 }
  

Однако, если я это сделаю, все set будет преобразовано в строку, а затем в byte[] . Сама строка может быть слишком большой.

Есть ли пример, как выполнить итерацию по набору и преобразовать его в байтбуфер? или я должен выполнить цикл для фрагментов набора?

Комментарии:

1. Я не совсем понимаю, что вы подразумеваете под «он не показывает, как перебирать байты». Может быть, вы могли бы отредактировать вопрос, чтобы показать код, который у вас есть до сих пор, и с чем конкретно вы застряли или работаете не так, как вы ожидаете. В Java обычно не сложно читать и записывать данные между каналами. Если у вас есть вопрос о java channel API, вам следует сосредоточить свой вопрос на этом.

2. Я попытался прояснить вопрос. Я не уверен, ищу ли я другой api GCP или другой api NIO.

3. Похоже, ваша проблема в том, что Joiner.on('n').join(set) возвращает полный массив байтов в памяти. Если вы хотите передавать исходные данные в потоковом режиме, вам понадобится API, который передает байтовое содержимое, а не возвращает все сразу.

Ответ №1:

Самый простой подход, о котором я мог подумать, был бы:

  try (WriteChannel writer = storage.writer(blobInfo)) {
   for(Integer val : set) {
     String valLine = val.toString()   'n';
     writer.write(ByteBuffer.wrap(valLine.getBytes(UTF_8));
   }
 }
  

Имейте в виду, это не очень эффективно. Это создает много маленьких байтбуферов. Вы могли бы значительно улучшить это, записав в один больший байтбуфер и периодически вызывая с ним writer.write.

Комментарии:

1. Спасибо, это с Iterators.partition выглядит лучше.

Ответ №2:

Чтобы избежать создания промежуточной строки со всеми байтами, которые вы можете загрузить из файла. Вы можете найти пример кода для выполнения загрузки из файла на разных языках здесь.

Комментарии:

1. загрузка из файла не помогает, потому что я хочу загружать непосредственно из набора.