如何将 S3 对象写入文件?

发布于 2024-12-08 13:41:58 字数 43 浏览 1 评论 0原文

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

What's the fastest way to write an S3 object (of which I have the key) to a file? I'm using Java.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

白况 2024-12-15 13:41:58

Java 7(于 2011 年 7 月发布)以来,有更好的方法: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 中,并在 finally 块中执行 in.close(); 应该是最安全的。

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

Since Java 7 (published back in July 2011), there’s a better way: Files.copy() utility from java.util.nio.file.

Copies all bytes from an input stream to a file.

So you need neither an external library nor rolling your own byte array loops. Two examples below, both of which use the input stream from S3Object.getObjectContent().

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

1) Write to a new file at specified path:

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

2) Write to a temp file in system's default tmp location:

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

(Without specifying the option to replace existing file, you'll get a FileAlreadyExistsException.)

Also note that getObjectContent() Javadocs urge you to close the input stream:

If you retrieve an S3Object, you should close this input stream as
soon as possible, because the object contents aren't buffered in
memory and stream directly from Amazon S3. Further, failure to close
this stream can cause the request pool to become blocked.

So it should be safest to wrap everything in try-catch-finally, and do in.close(); in the finally block.

The above assumes that you use the official SDK from Amazon (aws-java-sdk-s3).

木落 2024-12-15 13:41:58

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

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

While IOUtils.copy() and IOUtils.copyLarge() are great, I would prefer the old school way of looping through the inputstream until the inputstream returns -1. Why? I used IOUtils.copy() before but there was a specific use case where if I started downloading a large file from S3 and then for some reason if that thread was interrupted, the download would not stop and it would go on and on until the whole file was downloaded.

Of course, this has nothing to do with S3, just the IOUtils library.

So, I prefer this:

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

Note: This also means you don't need additional libraries

愁以何悠 2024-12-15 13:41:58

AmazonS3Client 类具有以下方法:

S3Object getObject(String bucketName, String key)

返回的 S3Object 具有方法...

java.io.InputStream getObjectContent()

..以流形式获取对象内容。我会使用 Apache Commons 中的 IOUtils,如下所示:

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

The AmazonS3Client class has the following method:

S3Object getObject(String bucketName, String key)

The returned S3Object has the method...

java.io.InputStream getObjectContent()

..which gets the object content as a stream. I'd use IOUtils from Apache Commons like this:

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

够运 2024-12-15 13:41:58

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

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

What about this one liner using a TransferManager:

TransferManagerBuilder.defaultTransferManager
  .download("bucket-name", "key", new File("."))
治碍 2024-12-15 13:41:58

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

如果您需要文件,你可以使用toFile方法。

Path path = Paths.get("file.txt");
s3.getObject(GetObjectRequest.builder().bucket(bucket).key(key).build(),
        path);
File file = path.toFile();

From AWS SDK for Java v2 released in 2017, you can just specify a Path for writing to the file.

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

If you need a File, you can use toFile method.

Path path = Paths.get("file.txt");
s3.getObject(GetObjectRequest.builder().bucket(bucket).key(key).build(),
        path);
File file = path.toFile();
-柠檬树下少年和吉他 2024-12-15 13:41:58
            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 );
            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 );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文