Import files from Amazon S3 in Java

Integrating Amazon S3 with Java applications is a common requirement for developers working with cloud storage. AWS SDK v2 provides a robust and efficient way to handle file importing. In this DevTip, we'll walk through setting up AWS SDK v2, securely configuring credentials, importing files from S3, handling exceptions, and optimizing performance.
Introduction to Amazon S3 and Java
Amazon S3 (Simple Storage Service) is a scalable cloud storage solution for storing and retrieving data. Java developers often interact with S3 to import files. AWS SDK v2 offers a streamlined API for these operations.
Setting up AWS SDK v2
Add the AWS SDK v2 dependencies to your project. For Maven, add to pom.xml
:
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.30.38</version>
</dependency>
For Gradle, add to build.gradle
:
implementation 'software.amazon.awssdk:s3:2.30.38'
Configuring AWS credentials
AWS SDK v2 supports multiple ways to configure credentials. The recommended approach is using environment variables or AWS credentials files.
Using environment variables:
export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
Or, store credentials in ~/.aws/credentials
:
[default]
aws_access_key_id = your_access_key
aws_secret_access_key = your_secret_key
Configuring the AWS region
Specifying the correct AWS region is crucial. Here's how to configure it:
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
// Configure the S3 client with a specific region
Region region = Region.US_EAST_1; // Choose your region
S3Client s3 = S3Client.builder()
.region(region)
.build();
Importing files from S3
Here's an example of importing a file from Amazon S3:
import software.amazon.awssdk.core.sync.ResponseTransformer;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import java.nio.file.Paths;
public class S3FileImporter {
public static void main(String[] args) {
String bucketName = "your-bucket-name";
String key = "path/to/your/file.txt";
String downloadPath = "downloaded-file.txt";
Region region = Region.US_EAST_1; // Choose your region
try (S3Client s3 = S3Client.builder()
.region(region)
.build()) {
GetObjectRequest request = GetObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();
s3.getObject(request, ResponseTransformer.toFile(Paths.get(downloadPath)));
System.out.println("File downloaded successfully to " + downloadPath);
} catch (S3Exception e) {
System.err.println("S3 error: " + e.awsErrorDetails().errorMessage());
} catch (Exception e) {
System.err.println("Unexpected error: " + e.getMessage());
}
}
}
Handling exceptions
When working with S3, handle specific exceptions:
try {
s3.getObject(request, ResponseTransformer.toFile(Paths.get(downloadPath)));
System.out.println("File downloaded successfully.");
} catch (software.amazon.awssdk.services.s3.model.NoSuchKeyException e) {
System.err.println("File not found: " + e.awsErrorDetails().errorMessage());
} catch (software.amazon.awssdk.services.s3.model.NoSuchBucketException e) {
System.err.println("Bucket not found: " + e.awsErrorDetails().errorMessage());
} catch (software.amazon.awssdk.services.s3.model.S3Exception e) {
System.err.println("S3 error: " + e.awsErrorDetails().errorMessage());
} catch (Exception e) {
System.err.println("Unexpected error: " + e.getMessage());
}
S3 client types
AWS SDK for Java v2 offers different client types:
Synchronous client (s3client)
The standard client for most applications. Operations block until completed.
Asynchronous client (s3asyncclient)
Ideal for non-blocking operations, returning CompletableFuture
objects:
import software.amazon.awssdk.services.s3.S3AsyncClient;
import java.util.concurrent.CompletableFuture;
S3AsyncClient asyncClient = S3AsyncClient.create();
CompletableFuture<GetObjectResponse> futureResponse =
asyncClient.getObject(request, AsyncResponseTransformer.toFile(Paths.get(downloadPath)));
futureResponse.whenComplete((response, error) -> {
if (error != null) {
System.err.println("Error: " + error.getMessage());
} else {
System.out.println("File downloaded successfully.");
}
});
Enhanced performance client (s3crtasyncclient)
For high-throughput, using the AWS Common Runtime (CRT):
import software.amazon.awssdk.services.s3.S3CrtAsyncClient;
S3CrtAsyncClient crtClient = S3CrtAsyncClient.builder()
.region(Region.US_EAST_1)
.build();
Optimizing performance
For large files, consider these techniques:
Streaming to disk
s3.getObject(request, ResponseTransformer.toFile(Paths.get("large-file.txt")));
This streams the file to disk, minimizing memory usage.
Multipart downloads
For files larger than a few hundred MB, use multipart downloads:
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.DownloadFileRequest;
S3TransferManager transferManager = S3TransferManager.builder()
.s3Client(s3AsyncClient)
.build();
DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder()
.getObjectRequest(request)
.destination(Paths.get("very-large-file.mp4"))
.build();
transferManager.downloadFile(downloadFileRequest)
.completionFuture()
.join();
Iam permissions
Ensure your IAM user or role has the minimum required permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::your-bucket-name/*", "arn:aws:s3:::your-bucket-name"]
}
]
}
Best practices
- Secure your AWS credentials.
- Use IAM roles with minimal permissions.
- Stream large files to disk.
- Implement robust error handling.
- Choose the appropriate S3 client type.
- Use the S3TransferManager for large files.
- Set appropriate timeouts.
Transloadit offers a managed solution for importing files, including from S3. Check out our S3 Import Robot and Java SDK.