Wednesday, July 26, 2017

read(byte[]), mark() and reset() in Java IO: InputStream

read(byte[])

The InputStream class also contains two read() methods which can read data from the InputStream's source into a byte array. These methods are:
  • int read(byte[])
  • int read(byte[], int offset, int length)
Reading an array of bytes at a time is much faster than reading one byte at a time, so when you can, use these read methods instead of the read() method.
The read(byte[]) method will attempt to read as many bytes into the byte array given as parameter as the array has space for. The read(byte[]) method returns an int telling how many bytes were actually read. In case less bytes could be read from the InputStream than the byte array has space for, the rest of the byte array will contain the same data as it did before the read started. Remember to inspect the returned int to see how many bytes were actually read into the byte array.
The read(byte[], int offset, int length) method also reads bytes into a byte array, but starts at offset bytes into the array, and reads a maximum of length bytes into the array from that position. Again, the read(byte[], int offset, int length) method returns an int telling how many bytes were actually read into the array, so remember to check this value before processing the read bytes.
For both methods, if the end of stream has been reached, the method returns -1 as the number of bytes read.
Here is an example of how it could looke to use the InputStream's read(byte[]) method:
InputStream inputstream = new FileInputStream("c:\\data\\input-text.txt");

byte[] data      = new byte[1024];
int    bytesRead = inputstream.read(data);

while(bytesRead != -1) {
  doSomethingWithData(data, bytesRead);

  bytesRead = inputstream.read(data);
}
inputstream.close();
First this example create a byte array. Then it creates an int variable named bytesRead to hold the number of bytes read for each read(byte[]) call, and immediately assigns bytesRead the value returned from the first read(byte[]) call.
Inside the while loop the doSomethingWithData() method is called, passing along the data byte array as well as how many bytes were read into the array as parameters. At the end of the while loop data is read into the byte array again.
It should not take much imagination to figure out how to use the read(byte[], int offset, int length) method instead of read(byte[]). You pretty much just replace the read(byte[]) calls with read(byte[], int offset, int length) calls.

mark() and reset()

The InputStream class has two methods called mark() and reset() which subclasses of InputStream may or may not support.
If an InputStream subclass supports the mark() and reset() methods, then that subclass should override the markSupported() to return true. If the markSupported() method returns false then mark() and reset() are not supported.
The mark() sets a mark internally in the InputStream which marks the point in the stream to which data has been read so far. The code using the InputStream can then continue reading data from it. If the code using the InputStream wants to go back to the point in the stream where the mark was set, the code calls reset() on the InputStream. The InputStream then "rewinds" and go back to the mark, and start returning (reading) data from that point again. This will of course result in some data being returned more than once from the InputStream.
The methods mark() and reset() methods are typically used when implementing parsers. Sometimes a parser may need to read ahead in the InputStream and if the parser doesn't find what it expected, it may need to rewind back and try to match the read data against something else.

@reference_1_tutorials.jenkov.com
Java IO: InputStream

No comments:

Post a Comment