繁体   English   中英

如何将 S3 对象写入文件?

[英]How to write an S3 object to a file?

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

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 )。

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

注意:这也意味着您不需要额外的库

AmazonS3Client 类具有以下方法:

S3Object getObject(String bucketName, String key)

返回的 S3Object 具有方法...

java.io.InputStream getObjectContent()

..它以流的形式获取对象内容。 我会像这样使用来自 Apache Commons 的 IOUtils:

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

这个使用 TransferManager 的班轮怎么样:

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

2017 年发布的 AWS SDK for Java v2 开始,您只需指定一个写入文件的Path即可。

s3.getObject(GetObjectRequest.builder().bucket(bucket).key(key).build(),
        ResponseTransformer.toFile(Paths.get("multiPartKey")));

https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/examples-s3-objects.html#download-object

如果需要File ,可以使用toFile方法。

Path path = Paths.get("file.txt");
s3.getObject(GetObjectRequest.builder().bucket(bucket).key(key).build(),
        path);
File file = path.toFile();
            byte[] content = IOUtils.toByteArray(myS3Object.getObjectContent());

            // path where to save the file
            File myFile = new File("/home/ayoub/Android/release.apk");

            //save content to file
            FileUtils.writeByteArrayToFile(apkFile, content);

            // OPTIONAL if you'd like to return a resource
            Resource resource = new ByteArrayResource( content );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM