This is a very simple example which will show you how to read your data sequentially:
public void readFile(String absoluteFilePath){
ByteBuffer buf = ByteBuffer.allocate(2+4+8) // creating a buffer that is suited for data you are reading
Path path = Paths.get(absoluteFilePath);
try(FileChannel fileChannel = (FileChannel)Files.newByteChannel(path,Enum.setOf(READ))){
while(true){
int bytesRead = fileChannel.read(buf);
if(bytesRead==-1){
break;
}
buf.flip(); //get the buffer ready for reading.
char c = buf.asCharBuffer().readChar(); // create a view buffer and read char
buf.position(buf.position() + 2); //now, lets go to the int
int i = buf.asIntBuffer().readInt(); //read the int
buf.position(buf.position()+ 4); //now, lets go for the double.
double d = buf.asDoubleBuffer().readDouble();
System.out.println("Character: " + c + " Integer: " + i + " Double: " + d);
buf.clear();
}
}catch(IOException e){
e.printStackTrace();
}// AutoClosable so no need to explicitly close
}
Now, assuming that you always write data as (char,int,double) into your file and that there are no chances where your data would be out of order or incomplete as (char,int) / (char,double), you can simply read the data randomly by specifying the position in the file, measured in bytes, from where to fetch the data as:
channel.read(byteBuffer,position);
In your case, the data is always 14 bytes in size as 2 + 4 + 8 so all your read positions will be multiples of 14.
First block at: 0 * 14 = 0
Second block at: 1 * 14 = 14
Third block at: 2 * 14 = 28
and so on..
Similar to reading, you can also write using
channel.write(byteBuffer,position)
Again, positions will be multiples of 14.
This applies in case of FileChannel which is a super class of ReadableByteChannel which is a dedicated channel for reading, WritableByteChannel which is a dedicated channel for writing and SeekableByteChannel which can do both reading and writing but is a little bit more complex.
When using channels and ByteBuffer, take care as to how you read. There is nothing to prevent me from reading 14 bytes as a set of 7 characters. Although this looks scary, this gives you complete flexibility on how you read and write data
char,doubleandintin your binary file, so when reading it you don't know how to read it i.e. must I first read achar, adoubleor anint?Channelif you want to do random reading and writing.FileChannelor aSeekableByteChannelwill do. However, I recommendFileChannelas it is much easier.Channelto solve this problem.