Как записать объект S3 в файл? - PullRequest
14 голосов
/ 07 октября 2011

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

Ответы [ 4 ]

25 голосов
/ 24 декабря 2015

Начиная с 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) Запись во временный файл в системном расположении 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).

15 голосов
/ 07 октября 2011

Хотя 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();

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

6 голосов
/ 07 октября 2011

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

S3Object getObject(String bucketName, String key)

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

java.io.InputStream getObjectContent()

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

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

3 голосов
/ 29 июля 2017

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

TransferManagerBuilder.defaultTransferManager
  .download("bucket-name", "key", new File("."))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...