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:
is.available() returns the number of bytes that can be read without blocking. It's rarely the total number of content bytes.
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).
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();
}
You saved my life with this piece of code man. Thanks.
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
not working ofcours, you're making the same mistake by using avaliable()!
very nice. for more java examples visit java2novice.com site
Post a Comment