#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. загрузка из файла не помогает, потому что я хочу загружать непосредственно из набора.