如何将S3对象写入文件?

将S3对象(我有密钥)写入文件的最快方法是什么? 我正在使用Java。

虽然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(); 

注意:这也意味着您不需要其他库

Java 7 (2011年7月发布)以来,有一种更好的方法:来自java.util.nio.file Files.copy()实用程序。

将输入流中的所有字节复制到文件。

因此, 既不 需要外部库也不需要滚动自己的字节数组循环 。 以下两个示例,两个示例都使用来自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块中。

以上假设您使用来自Amazon的官方SDK( aws-java-sdk-s3 )。

AmazonS3Client类具有以下方法:

 S3Object getObject(String bucketName, String key) 

返回的S3Object有方法…

 java.io.InputStream getObjectContent() 

..which将对象内容作为流获取。 我会像Apache Commons一样使用IOUtils:

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

使用TransferManager这个衬管怎么样:

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