Search code examples
javainputstreambytearrayinputstreamioutils

Does IOUtils.toByteArray(inputStream) method internally close inputStream object?


Here is my code flow for which file content is getting lost and I think may be IOUtils.toByteArray() line is problem, please guide what is actually going wrong here.

File content getting lost :

InputStream stream = someClient.downloadApi(fileId);
byte[] bytes = IOUtils.toByteArray(stream); 
String mimeType = CommonUtils.fileTypeFromByteArray(bytes);
String fileExtension=FormatToExtensionMapping.getByFormat(mimeType).getExtension();
String filePath = configuration.getDownloadFolder() + "/" ;
String fileName = UUID.randomUUID() + fileExtension;    
File file = new File(filePath+fileName);    
file.createNewFile();    
FileUtils.copyInputStreamToFile(stream,file);    
int length = (int)file.length();

Now length value here is 0 basically no content. Let me tell you that inputStream received from downloadApi() has content for sure thats given. But if I try below modification in code then I'm getting length of file.

File content NOT getting lost:

InputStream stream = someClient.downloadApi(fileId);
byte[] bytes = IOUtils.toByteArray(stream);
String mimeType = CommonUtils.fileTypeFromByteArray(bytes);
String fileExtension=FormatToExtensionMapping.getByFormat(mimeType).getExtension();
String filePath = configuration.getDownloadFolder() + "/" ;
String fileName = UUID.randomUUID() + fileExtension;
stream = new ByteArrayInputStream(bytes); //Again converted bytes to stream    
File file = new File(filePath+fileName);    
file.createNewFile();    
FileUtils.copyInputStreamToFile(stream,file);    
int length = (int)file.length();

Now here I'm getting file content. Can some body tell what is technically wrong here in first code snippet ?

TIA


Solution

  • No it doesn't.

    The first version of your code (reproduced below with some added commentary) fails because you are reading from a stream that is already at the end of stream position.

    InputStream stream = someClient.downloadApi(fileId);
    
    // This reads the entire stream to the end of stream.
    byte[] bytes = IOUtils.toByteArray(stream);
    
    String mimeType = CommonUtils.fileTypeFromByteArray(bytes);
    String fileExtension = 
            FormatToExtensionMapping.getByFormat(mimeType).getExtension();
    String filePath = configuration.getDownloadFolder() + "/" ;
    String fileName = UUID.randomUUID() + fileExtension;    
    File file = new File(filePath+fileName);    
    file.createNewFile();    
    
    // Now you attempt to read more data from the stream.
    FileUtils.copyInputStreamToFile(stream,file);    
    
    int length = (int)file.length();
    

    When you try to copy from a stream that is at the end of stream, you get ... zero bytes. And that means you get an empty output file.