Какой самый быстрый способ записать объект S3 (из которого у меня есть ключ) в файл? Я использую Java.
Как написать объект S3 в файл?
Ответ 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("."))