Java Reference
In-Depth Information
Reading Mixed Data
The primes.txt file that we created in the previous chapter contains data of three different types. We
have the string length as a binary value of type double of all things, followed by the string itself
describing the prime value, followed by the binary prime value as type long . Reading this file is a little
trickier than it looks at first sight.
To start with we will set up the file input stream and obtain the channel for the file. Since, apart from
the name of the file, this is exactly as in the previous example we won't repeat it here. Of course, the big
problem is that we don't know ahead of time exactly how long the strings are. We have two strategies to
deal with this:
We can read the string length in the first read operation, then read the string and the binary
prime value in the next. The only downside to this approach is that it's not a particularly
efficient way to read the file as we will have read operations that each read a very small
amount of data.
We can set up a sizable byte buffer of an arbitrary capacity and just fill it with bytes from the
file. We can then sort out what we have in the buffer. The problem with this approach is that
the buffer's contents may well end part way through one of the data items from the file. We
will have to do some work to detect this and figure out what to do next but this will be much
more efficient than the first approach since we will vastly reduce the number of read
operations that are necessary to read the entire file.
Let's try the first approach first as it's easier.
To read the string length we need a byte buffer with a capacity to hold a single value of type double :
ByteBuffer lengthBuf = ByteBuffer.allocate(8);
We can create a byte buffer to hold both the string and the binary prime value, but only after we know
the length of the string. We will also need an array of type byte[] to hold the string characters -
remember, we wrote the string as bytes, not Unicode characters. Some variables will come in handy:
int strLength = 0; // Stores the string length
ByteBuffer buf = null; // Stores a reference to the second byte buffer
byte[] strChars = null; // Stores a reference to an array to hold the string
Since we need two read operations to get at all the data for a single prime, we will adopt a different
strategy for reading the entire file. We will put both read operations in an indefinite loop and use a
break statement to exit the loop when we hit the end-of-file (EOF). Here's how we can read the file:
while(true) {
if(inChannel.read(lengthBuf) == -1) // Read the string length, if its EOF
break; // exit the loop
lengthBuf.flip();
strLength = (int)lengthBuf.getDouble(); // Extract length & convert to int
Search WWH ::




Custom Search