Tuesday, March 31, 2009

Reading Bytes From Any InputStream

Reading Bytes From Any InputStream

Most of the time, we do get available bytes in one stroke by calling read() API in InputStream.

long length = is.available();
byte[] bytes = new byte[(int) length];
is.read(bytes);
System.out.println(new String(bytes));

The above given code may not work for InputStream which reads data from socket. Means, this will not read full data from the stream, reason could be
  • network delay in transmitting content
  • mounted filesystem unlinked
  • message size is exceeds TCP window size
  • etc.,
.

Hence, the following code will make sure and helps us to check whether all the bytes are received or not.


public static byte[] getBytesFromInputStream(InputStream is)
throws IOException {

// Get the size of the file
long length = is.available();

if (length > Integer.MAX_VALUE) {
// File is too large
}

// Create the byte array to hold the data
byte[] bytes = new byte[(int) length];

// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
offset += numRead;
}

// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file ");
}

// Close the input stream and return bytes
is.close();
return bytes;
}

Read more : Reverse Reading

7 comments:

Anonymous said...

is.available() returns the number of bytes that can be read without blocking. It's rarely the total number of content bytes.

Jones91 said...

that's no good solution. notice:

public int available ()

Returns an estimated number of bytes that can be read or
skipped without blocking for more input.
Note that this method provides such a weak guarantee
that it is not very useful in practice.
Firstly, the guarantee is "without blocking for more input"
rather than "without blocking": a read may still block
waiting for I/O to complete &mdash the guarantee is
merely that it won't have to wait indefinitely for data to be
written. The result of this method should not be used as a
license to do I/O on a thread that shouldn't be blocked.
Secondly, the result is a conservative estimate and may be
significantly smaller than the actual number of bytes
available. In particular, an implementation that always
returns 0 would be correct. In general, callers should only
use this method if they'd be satisfied with treating the
result as a boolean yes or no answer to the question "is
there definitely data ready?".
Thirdly, the fact that a given number of bytes is "available"
does not guarantee that a read or skip will actually read or
skip that many bytes: they may read or skip fewer.
It is particularly important to realize that you must not use
this method to size a container and assume that you can
read the entirety of the stream without needing to resize
the container. Such callers should probably write
everything they read to a ByteArrayOutputStream and
convert that to a byte array. Alternatively, if you're reading
from a file, length() returns the current length of the file
(though assuming the file's length can't change may be
incorrect, reading a file is inherently racy).

Anonymous said...

consider the following solution:

public static byte[] getFileBytes(InputStream is) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
BufferedInputStream fin = new BufferedInputStream(is);
byte buf[] = new byte[8192];
int ret = 0;
while ((ret = fin.read(buf)) != -1) {
bout.write(buf, 0, ret);
}
fin.close();
return bout.toByteArray();
}

Prodogy11 said...

You saved my life with this piece of code man. Thanks.

java67 said...

Nice tip but this can be achieved in 3 lines by using Guava library as shown in 5 ways to convert InputStream to String in Java

Anonymous said...

not working ofcours, you're making the same mistake by using avaliable()!

java2novice said...

very nice. for more java examples visit java2novice.com site

Post a Comment

Recent Posts

Unix Commands | List all My Posts

Texts

This blog intended to share the knowledge and contribute to JAVA Community such a way that by providing samples and pointing right documents/webpages. We try to give our knowledege level best and no guarantee can be claimed on truth. Copyright and Terms of Policy refer blogspot.com