Reading Chunks of Data from a Stream
Input and output are often the performance bottlenecks in a program. Reading from or writing to disk can be hundreds of times slower than reading from or writing to memory; network connections and user input are even slower. While disk capacities and speeds have increased over time, they have never kept pace with CPU speeds. Therefore, it's important to minimize the number of reads and writes a program actually performs.
All input streams have overloaded read( ) methods that read chunks of contiguous data into a byte array. The first variant tries to read enough data to fill the array. The second variant tries to read length bytes of data starting at position offset into the array. Neither of these methods is guaranteed to read as many bytes as you want. Both methods return the number of bytes actually read, or -1 on end of stream.
public int read(byte[] data) throws IOException public int read(byte[] data, int offset, int length) throws IOException
The default implementation of these methods in the java.io.InputStream class merely calls the basic read( ) method enough times to fill the requested array or subarray. Thus, reading 10 bytes of data takes 10 times as long as reading 1 byte of data. However, most subclasses of InputStream override these methods with more efficient methods, perhaps native, that read the data from the underlying source as a block.
For example, to attempt to read 10 bytes from System.in, you could write the following code:
try { byte[] b = new byte[10]; System.in.read(b); } catch (IOException ex) { System.err.println("Couldn't read from System.in!"); }
Reads don't always succeed in getting as many bytes as you want. Conversely, there's nothing to stop you from trying to read more data into the array than will fit. If you do this, read( ) tHRows an ArrayIndexOutOfBoundsException. For example, the following code loops repeatedly until it either fills the array or sees the end of stream:
try { byte[] b = new byte[100]; int offset = 0; while (offset < b.length) { int bytesRead = System.in.read(b, offset, b.length - offset); if (bytesRead == -1) break; // end of stream offset += bytesRead; } } catch (IOException ex) { System.err.println("Couldn't read from System.in!"); }