Как написать объект S3 в файл?

Какой самый быстрый способ записать объект S3 (из которого у меня есть ключ) в файл? Я использую Java.

Ответ 1

В то время как IOUtils.copy() и IOUtils.copyLarge() великолепны, я предпочел бы, чтобы старый школьный путь проходил через входной поток до тех пор, пока входной поток не вернет -1. Зачем? Раньше я использовал IOUtils.copy(), но был конкретный случай использования, когда я начал загружать большой файл из S3, а затем по какой-то причине, если этот поток был прерван, загрузка не прекращалась, и он продолжался и продолжался до тех пор, пока был загружен весь файл.

Конечно, это не имеет ничего общего с S3, это только библиотека IOUtils.

Итак, я предпочитаю это:

InputStream in = s3Object.getObjectContent();
byte[] buf = new byte[1024];
OutputStream out = new FileOutputStream(file);
while( (count = in.read(buf)) != -1)
{
   if( Thread.interrupted() )
   {
       throw new InterruptedException();
   }
   out.write(buf, 0, count);
}
out.close();
in.close();

Примечание. Это также означает, что вам не нужны дополнительные библиотеки

Ответ 2

Так как Java 7 (опубликовано еще в июле 2011 года), это лучший способ: Files.copy() от java.util.nio.file.

Копирует все байты из входного потока в файл.

Таким образом, вам не нужна внешняя библиотека и не переверните свои собственные байтовые байтовые байты . Два примера ниже, оба из которых используют входной поток из S3Object.getObjectContent().

InputStream in = s3Client.getObject("bucketName", "key").getObjectContent();

1) Запись в новый файл по указанному пути:

Files.copy(in, Paths.get("/my/path/file.jpg"));

2) Запись в файл temp в системном по умолчанию местоположении tmp:

File tmp = File.createTempFile("s3test", "");
Files.copy(in, tmp.toPath(), StandardCopyOption.REPLACE_EXISTING);

(Без указания опции для замены существующего файла вы получите FileAlreadyExistsException.)

Также обратите внимание, что getObjectContent() Javadocs настоятельно призывает закрыть входной поток:

Если вы извлекаете S3Object, вы должны закрыть этот входной поток как как можно скорее, поскольку содержимое объекта не буферизуется памяти и потока непосредственно от Amazon S3. Кроме того, неспособность закрыть этот поток может привести к блокировке пула запросов.

Таким образом, должно быть безопаснее обернуть все в try-catch-finally и сделать in.close(); в блоке finally.

Вышеизложенное предполагает, что вы используете официальный SDK из Amazon (aws-java-sdk-s3).

Ответ 3

Класс AmazonS3Client имеет следующий метод:

S3Object getObject(String bucketName, String key)

Возвращенный объект S3Object имеет метод...

java.io.InputStream getObjectContent()

.. который получает содержимое объекта как поток. Я бы использовал IOUtils из Apache Commons, как это:

IOUtils.copy(s3Object.getObjectContent(), new FileOutputStream(new File(filepath)));

Ответ 4

Как насчет этого одного лайнера с помощью TransferManager:

TransferManagerBuilder.defaultTransferManager
  .download("bucket-name", "key", new File("."))