33

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;     
}
itro
  • 7,006
  • 27
  • 78
  • 121
  • 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. – Sam Palmer Jun 27 '12 at 10:17
  • 3
    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. – Peter Lawrey Jun 27 '12 at 10:17
  • Please explai your use case. You probably just want a FileInputStream. How do you plan to use it once you have it? – John Watts Jun 27 '12 at 10:20
  • 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... – Sam Palmer Jun 27 '12 at 10:22
  • This seems likely to be _strictly_ slower than reading from a `FileInputStream`, no? – Louis Wasserman Jun 27 '12 at 10:33
  • Sam Palmer, Please provide an example. – itro Jun 27 '12 at 11:53
  • @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. – Maarten Bodewes Jul 01 '12 at 23:41

5 Answers5

58

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));
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
npe
  • 15,395
  • 1
  • 56
  • 55
  • 21
    As noted in my answer, Java 7 already contains a readFileToByteArray in the Files class, no need for an additional library. – Maarten Bodewes Jun 27 '12 at 12:31
  • I meant [Files.readAllBytes](http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#readAllBytes%28java.nio.file.Path%29) in the previous comment. Sorry about that, let's save you all some searching. – Maarten Bodewes Jun 27 '23 at 10:11
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.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • 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. – Maarten Bodewes Jul 28 '19 at 21:16
  • 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. – Binita Bharati Jun 27 '23 at 10:27
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.

Qwerky
  • 18,217
  • 6
  • 44
  • 80
  • I'm using it to upload file to ftp through FTPClient commons Apache. – itro Jun 27 '12 at 11:33
  • 2
    I would suggest [the try-with-resources Statement](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) instead of "remember to close the input stream". – Franklin Yu Feb 15 '19 at 19:34
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
npe
  • 15,395
  • 1
  • 56
  • 55
Sam Palmer
  • 1,675
  • 1
  • 25
  • 45
  • 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)`](https://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#read(java.nio.ByteBuffer)). 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. – Maarten Bodewes Oct 24 '22 at 13:11
  • Even better would be to use [`map`](https://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#map(java.nio.channels.FileChannel.MapMode,%20long,%20long)) which is likely to save you a lot of memory and probably a *memory copy* as well. – Maarten Bodewes Oct 24 '22 at 13:13
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/

Buddy
  • 2,074
  • 1
  • 20
  • 30