skip to Main Content

I would like to be able to download a file from an S3 bucket to my local computer using a Java Lambda Function. I have written the code below in a Java Lambda Function which is able to download the file to the /tmp directory of AWS. But then what are my options? How do I get the file downloaded to my local computer? Thank you.

    S3TransferManager transferManager = S3TransferManager.create();
     
    DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder()
                    .getObjectRequest(b -> b.bucket(bucketName).key(key))
                    .addTransferListener(LoggingTransferListener.create())
                    .destination(Paths.get(downloadedFileWithPath))
                    .build();

    FileDownload downloadFile = transferManager.downloadFile(downloadFileRequest);

    CompletedFileDownload downloadResult = downloadFile.completionFuture().join();
    logger.info("Content length [{}]", downloadResult.response().contentLength());
    return downloadResult.response().contentLength();

2

Answers


  1. One option is to modify your Java Lambda function to upload the downloaded file to a different S3 bucket that you have access to in your local computer. Then, you can use the AWS CLI (Command Line Interface) to download the file from the S3 bucket to your local computer.

    Login or Signup to reply.
  2. I can provide with code example that will allows you to download files from AWS Lambda.

    public class Handler implements RequestHandler<Object, APIGatewayProxyResponseEvent> {
    
        public APIGatewayProxyResponseEvent handleRequest(Object input, Context context) {
    
            // put here goes your s3 code
            
            // This is how to form file upload response:
            APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
            try {
                response.setStatusCode(200);
                response.setBody(Files.readString(Paths.get(path), StandardCharsets.UTF_8));
                response.setHeaders(Map.of(
                        "Content-Disposition", "attachment; filename="" + key + """,
                        "Content-Length", String.valueOf(downloadResult.response().contentLength())
                ));
                return response;
            } catch (IOException e) {
                response.setStatusCode(500);
            }
            return response;
        }
    }
    
    implementation 'com.amazonaws:aws-lambda-java-events:3.11.0'
    

    Modify that as you wish, but consider next for your file distributions:

    1. Response is only allowing body to be String. This is not optimal and just an example. You should use InputStream instead in real application. For that you need to looks for the lib that can produce HTTP responses from input stream.

    2. By analogy you shouldn’t save file from S3 to file, you can use S3Client to get InputStream, buffer it and pass to HTTP response.

    3. Don’t stream file via AWS Lambda and use pre-signed URL as @jarmod proposed. This will require you downloading file manually though.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search