Reading a Binary Input Stream into a Single Byte Array in Java

Reading a binary input stream into a single byte array in Java

The simplest approach IMO is to use Guava and its ByteStreams class:

byte[] bytes = ByteStreams.toByteArray(in);

Or for a file:

byte[] bytes = Files.toByteArray(file);

Alternatively (if you didn't want to use Guava), you could create a ByteArrayOutputStream, and repeatedly read into a byte array and write into the ByteArrayOutputStream (letting that handle resizing), then call ByteArrayOutputStream.toByteArray().

Note that this approach works whether you can tell the length of your input or not - assuming you have enough memory, of course.

Convert InputStream to byte array in Java

You can use Apache Commons IO to handle this and similar tasks.

The IOUtils type has a static method to read an InputStream and return a byte[].

InputStream is;
byte[] bytes = IOUtils.toByteArray(is);

Internally this creates a ByteArrayOutputStream and copies the bytes to the output, then calls toByteArray(). It handles large files by copying the bytes in blocks of 4KiB.

How do I read / convert an InputStream into a String in Java?

A nice way to do this is using Apache Commons IOUtils to copy the InputStream into a StringWriter... Something like

StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, encoding);
String theString = writer.toString();

or even

// NB: does not close inputStream, you'll have to use try-with-resources for that
String theString = IOUtils.toString(inputStream, encoding);

Alternatively, you could use ByteArrayOutputStream if you don't want to mix your Streams and Writers.

How does inputstream per byte reading work?

This will depend on the external process that is sending data to System.in. It could be a command shell, an IDE, or another process.

In the typical case of a command shell, the shell will have a character encoding configured. (chcp on Windows, locale charmap on Linux.)

The character encoding determines how a graphical character or glyph is coded as a number. For example, a Windows machine might use a "code page" of "Windows-1251" and encode "Я" as one byte (0xCF). Or, it could use UTF-8 and encode "Я" as two bytes (0xD0 0xAF), or UTF-16 and use two different bytes (0x04 0x2F).

Your results show that the process sending data to your Java program is using UTF-8 as an encoding.

What is the most efficient way to read a variable data length from binary input stream

You should be able to use the read(byte[], int, int) method to fill a byte array.

int numRead= 0;
int total =0;
int readSize =56;
while(numRead >= 0 && total < readSize) {
numRead = this.in.read(inBytes, total, readSize - total);
if(numRead > 0) {
total += numRead;
}
}

This is similar to what you've got, though it doesn't limit to 1 byte at a time.

Reading from a binary file to byte array in j2me

Since you are always dealing with bytes, you should use an InputStream rather than an InputStreamReader.

Add the Javadoc says:

An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset. The charset that it uses may be specified by name or may be given explicitly, or the platform's default charset may be accepted.

And the read() method reads a "character":

On the other hand, an InputStream represents an input stream of bytes:

public abstract int read() throws IOException

Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

(And for kicks, here's a dated article about "buffered readers" in j2me)

In Java, how can I convert an InputStream into a byte array (byte[])?

The simplest way is to create a new ByteArrayOutputStream, copy the bytes to that, and then call toByteArray:

public static byte[] readFully(InputStream input) throws IOException
{
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
while ((bytesRead = input.read(buffer)) != -1)
{
output.write(buffer, 0, bytesRead);
}
return output.toByteArray();
}

Reading Strings and Binary from the same FileInputStream

If you genuinely have a file (rather than something harder to seek in, e.g. a network stream) then I suggest something like this:

  • Open the file as a FileInputStream
  • Wrap it in InputStreamReader and a BufferedReader
  • Read the text, so you can find out how much content there is
  • Close the BufferedReader (which will close the InputStreamReader which will close the FileInputStream)
  • Reopen the file
  • Skip to (total file length - binary content length)
  • Read the rest of the data as normal

You could just call mark() at the start of the FileInputStream and then reset() and skip() to get to the right place if you want to avoid reopening the file. (I was looking for an InputStream.seek() but I can't see one - I can't remember wanting it before in Java, but does it really not have one? Ick.)



Related Topics



Leave a reply



Submit