I recently came across this article which provided a nice introduction to memory mapping files and how it can be shared between two processes. Here is the code for the process that is being read in the file:
import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; public class MemoryMapReader { public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException { FileChannel fc = new RandomAccessFile(new File("c:/tmp/mapped.txt"), "rw").getChannel(); long bufferSize=8*1000; MappedByteBuffer mem = fc.map(FileChannel.MapMode.READ_ONLY, 0, bufferSize); long oldSize=fc.size(); long currentPos = 0; long xx=currentPos; long startTime = System.currentTimeMillis(); long lastValue=-1; for(;;) { while(mem.hasRemaining()) { lastValue=mem.getLong(); currentPos +=8; } if(currentPos < oldSize) { xx = xx + mem.position(); mem = fc.map(FileChannel.MapMode.READ_ONLY,xx, bufferSize); continue; } else { long end = System.currentTimeMillis(); long tot = end-startTime; System.out.println(String.format("Last Value Read %s , Time(ms) %s ",lastValue, tot)); System.out.println("Waiting for message"); while(true) { long newSize=fc.size(); if(newSize>oldSize) { oldSize = newSize; xx = xx + mem.position(); mem = fc.map(FileChannel.MapMode.READ_ONLY,xx , oldSize-xx); System.out.println("Got some data"); break; } } } } } }
However, I have a few comments / questions regarding this approach:
If we only read in an empty file, then run
long bufferSize=8*1000; MappedByteBuffer mem = fc.map(FileChannel.MapMode.READ_ONLY, 0, bufferSize); long oldSize=fc.size();
8000 bytes will be allocated here, which will now expand the file. The buffer that is returned has a limit of 8000 and a position of 0, so the reader can continue reading clean data. After that, the reader will stop as currentPos == oldSize .
Presumably, the author now appears (the code is skipped, since most of them are simple and can be specified from the site) - he uses the same buffer size, so he will write the first 8000 bytes, and then allocates another 8000, expanding the file. Now, if we assume that this process stops at this moment, and we return to the reader, the reader sees the new file size and selects the remainder (so from position 8000 to 1600) and starts reading again, reading in another garbage ...
I am a little confused if there is a reason for synchronizing these two operations. As far as I can see, any map call can expand the file with a really empty buffer (filled with zeros), or the author could just decrypt the file, but havenβt written anything yet ...