I have a service
method which returns a File Object
from AWS S3 bucket given a fileName
. I would like to convert the S3Object to a File object and return the same.
I do not want to use any temp location to download the file, just want to convert the S3Object
to File
Object and return it.
I would also like to use try
with resources and IOUtils
for the same.
My question is what is the right way to perform com.amazonaws.util.IOUtils.copy(InputStream in, OutputStream out)
method to get the File Object. This File object will be used by the calling method for further processing hence I do not want to save it locally. I tried something like this but it throws FileNotFoundException.
I am sure I am missing something in this, may be IOUtils.copy has to be used differently. or I am not using try with resources correctly.
public File getFileFromBucket(String fileName) {
GetObjectRequest getObjectRequest = new GetObjectRequest(aWSBucketName, fileName);
S3Object s3Object = aWSS3client.getObject(getObjectRequest);
File s3File = new File(fileName);
try (FileOutputStream fos = new FileOutputStream(s3File)) { //throws Exception
IOUtils.copy(s3Object.getObjectContent(), fos);
} catch (IOException e) {
log.debug("IOException Occurred while fetching file {}", fileName);
e.printStacktrace();
}
return s3File;
}
What is the right way to return the File? Any help is appreciated, thanks in advance.
Edit
If I do not want to save a File Object locally, is it advisable to return the InputStream to the calling method?
As mentioned, the calling method uses apache poi
library to parse the excel file.
org.apache.poi.xssf.usermodel.XSSFWorkbook.XSSFWorkbook(InputStream is)
this method anyway takes InputStream
as a param.
I do not know why I wanted to convert it to a File to begin with.
Question:
Is it advisable to send the S3Object.getObjectContent()
as an InputStream
to the calling method or is there a better way to do it?
After consulting my seniors I found that it is fine to send the InputStream
to the calling method.
If the InputStream
needs to be save to a local system, then IOUtils.copy
can be used whenever necessary.
Conversion of InputStream
to File
and then back to InputStream
is a waste of computation.
Hence my method is simply returning the ObjectContent
like this:
public InputStream getFileInputStreamFromBucket(String fileName) {
GetObjectRequest getObjectRequest = new GetObjectRequest(aWSBucketName, fileName);
S3Object s3Object = aWSS3client.getObject(getObjectRequest);
InputStream fileInputStream = s3Object.getObjectContent();
log.debug("File Input Stream fetched from s3 bucket for File {} ", fileName);
return fileInputStream;
}
This seems to be the right choice.
If anyone has a better way to send back the InputStream
please feel free to Post an answer.