如何用Java将远程服务器文件流式上传至S3且无需本地存储?
I want to stream a file stored on a remote server (e.g.,
http://example.com/example.pdf) directly to AWS S3 without saving it to the server running my code. Here's the code I currently have:URL url = new URL(" http://example.com/example.pdf"); URLConnection connection = url.openConnection(); InputStream in = connection.getInputStream(); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("application/pdf"); metadata.setContentLength(in.available()); PutObjectRequest objectRequest = new PutObjectRequest("bucket","key",in,metadata); PutObjectResult result = s3AwsClient.putObject(objectRequest);Is this approach valid for achieving the goal of not saving the file locally?
Absolutely! Your core approach does work for streaming the remote file directly to S3 without saving it to your local server—you’re already using the right pattern by passing the remote InputStream straight into the PutObjectRequest. That said, there are a few critical tweaks to fix potential issues and make the code more robust:
- Stop using
in.available()for content length: Theavailable()method only returns the number of bytes you can read without blocking right now, not the full file size. For remote files, this will almost always give you an incorrect value. Instead:- Fetch the
Content-Lengthheader from the remote connection (if it’s provided):long contentLength = connection.getContentLengthLong(); if (contentLength != -1) { metadata.setContentLength(contentLength); } - Or, skip setting the content length entirely—AWS S3 will automatically calculate it as it streams the data.
- Fetch the
- Clean up resources properly: Wrap your
InputStreamin a try-with-resources block to ensure it gets closed even if an error occurs during the upload:try (InputStream in = connection.getInputStream()) { ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType("application/pdf"); long contentLength = connection.getContentLengthLong(); if (contentLength != -1) { metadata.setContentLength(contentLength); } PutObjectRequest objectRequest = new PutObjectRequest("bucket", "key", in, metadata); PutObjectResult result = s3AwsClient.putObject(objectRequest); } catch (IOException e) { // Handle connection or upload errors here e.printStackTrace(); } - Consider a more robust HTTP client: Basic
URLConnectionworks, but libraries like Apache HttpClient or OkHttp offer better handling of redirects, timeouts, and retries for remote requests. But even withURLConnection, your core "stream directly to S3" logic is solid.
The big win here is that you never write the file to local disk—you’re piping the data straight from the remote server’s input stream into S3’s upload stream. That’s exactly the no-local-save workflow you’re after.
内容的提问来源于stack exchange,提问作者Sanjay Remesh

