How to create ByteArrayInputStream from a file in Java?
Asked Answered
L

5

34

I have a file that can be any thing like ZIP, RAR, txt, CSV, doc etc. I would like to create a ByteArrayInputStream from it.
I'm using it to upload a file to FTP through FTPClient from Apache Commons Net.

Does anybody know how to do it?

For example:

String data = "hdfhdfhdfhd";
ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes());

My code:

public static ByteArrayInputStream retrieveByteArrayInputStream(File file) {
    ByteArrayInputStream in;

    return in;     
}
Levison answered 27/6, 2012 at 10:12 Comment(7)
For file reading in bytes I use RandomAccessFile and transfer the whole file bytes into a byte array first. I found this to be an extremely fast way for reading files in bytes.Kratzer
Why would you ever need to do this? You can do this by copying the a FileInputStream to a ByteArrayOutputStream and then creating a ByteArrayInputStream from that. Its rather pointless of course.Lucianaluciano
Please explai your use case. You probably just want a FileInputStream. How do you plan to use it once you have it?Principally
It is slightly unnecessary I admit, but I found it was one of the fastest way for reading files, if speed is your thing. Then again I know just use C...Kratzer
This seems likely to be strictly slower than reading from a FileInputStream, no?Symphonious
Sam Palmer, Please provide an example.Levison
@LouisWasserman I would think so because you are basically waiting for the file to be in memory before transferring it. Besides that (and, in my opinion, more importantly) it will claim memory without there being any need for it.Outsider
G
59

Use the FileUtils#readFileToByteArray(File) from Apache Commons IO, and then create the ByteArrayInputStream using the ByteArrayInputStream(byte[]) constructor.

public static ByteArrayInputStream retrieveByteArrayInputStream(File file) {
    return new ByteArrayInputStream(FileUtils.readFileToByteArray(file));
}
Gastight answered 27/6, 2012 at 10:18 Comment(2)
As noted in my answer, Java 7 already contains a readFileToByteArray in the Files class, no need for an additional library.Outsider
I meant Files.readAllBytes in the previous comment. Sorry about that, let's save you all some searching.Outsider
O
27

The general idea is that a File would yield a FileInputStream and a byte[] a ByteArrayInputStream. Both implement InputStream so they should be compatible with any method that uses InputStream as a parameter.

Methods should generally accept InputStream rather than any implementing classes such as ByteArrayInputStream for reading bytes otherwise the whole generalization / raison d'être of byte streams is lost.


Putting all of the file contents in a ByteArrayInputStream can be done of course:

  1. read in the full file into a byte[]; Java version >= 7 contains a convenience method called readAllBytes to read all data from a file;
  2. create a ByteArrayInputStream around the file content, which is now in memory.

Note that this may not be optimal solution for very large files - all the file will stored in memory at the same point in time. Using the right stream for the job is important.

Outsider answered 27/6, 2012 at 10:19 Comment(2)
Small note: Java also contains ways of memory mapping files, which may be more beneficial if random reads and writes need to be performed. Streaming data from files is not the only option nor is it always the best one.Outsider
Excellent note about reading large files into an in memory byte array in order to convert to ByteArrayInputStream. It totally defeats the purpose of InputStream. Thanks for pointing it out.Seko
N
5

A ByteArrayInputStream is an InputStream wrapper around a byte array. This means you'll have to fully read the file into a byte[], and then use one of the ByteArrayInputStream constructors.

Can you give any more details of what you are doing with the ByteArrayInputStream? Its likely there are better ways around what you are trying to achieve.

Edit:
If you are using Apache FTPClient to upload, you just need an InputStream. You can do this;

String remote = "whatever";
InputStream is = new FileInputStream(new File("your file"));
ftpClient.storeFile(remote, is);

You should of course remember to close the input stream once you have finished with it.

Nabila answered 27/6, 2012 at 10:21 Comment(2)
I'm using it to upload file to ftp through FTPClient commons Apache.Levison
I would suggest the try-with-resources Statement instead of "remember to close the input stream".Eisenach
K
3

This isn't exactly what you are asking, but is a fast way of reading files in bytes.

File file = new File(yourFileName);
RandomAccessFile ra = new RandomAccessFile(yourFileName, "rw"):
byte[] b = new byte[(int)file.length()];
try {
    ra.read(b);
} catch(Exception e) {
    e.printStackTrace();
}

//Then iterate through b
Kratzer answered 27/6, 2012 at 10:21 Comment(2)
Iterating through a byte array is generally not the way to go. If you go this way and iterate through byte array b then you are better off using RandomAccessFile#getChannel and then use read(ByteBuffer dst). Or you can just wrap it with a ByteArrayInputStream as that may be wrapped itself with a DataStream. You generally don't want to perform low level marshalling of bytes into lower level variables such as ints and strings.Outsider
Even better would be to use map which is likely to save you a lot of memory and probably a memory copy as well.Outsider
M
2

This piece of code comes handy:

private static byte[] readContentIntoByteArray(File file)
{
  FileInputStream fileInputStream = null;
  byte[] bFile = new byte[(int) file.length()];
  try
  {
     //convert file into array of bytes
     fileInputStream = new FileInputStream(file);
     fileInputStream.read(bFile);
     fileInputStream.close();
  }
  catch (Exception e)
  {
     e.printStackTrace();
  }
  return bFile;
}

Reference: http://howtodoinjava.com/2014/11/04/how-to-read-file-content-into-byte-array-in-java/

Mick answered 1/9, 2015 at 2:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.