I came up with this question because I want to recognize when a change occurred in the memory-mapped file. So I can handle appropriately on the second program.
Is this possible with the Watch Service?
EDIT:
To get events I used this demo code from the java docs.
I also used a Get-Content -Path "test.txt" -Wait inside PowerShell to monitor the file for changes.
This is the code I wrote for the test. Running it several times with different values put in the TTT class doesn't trigger events but the changes are there when opening the file.
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class App1 {
// private static long count = 1_000_000L; // ~1MB
private static long size = 100_000L; // ~100KB
public static void main(String[] args) throws IOException, InterruptedException {
RandomAccessFile memoryMappedFile = new RandomAccessFile("test/test.txt", "rw");
MappedByteBuffer out = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, size);
// Changing data in here and running again wont trigger an event
// But the changes are actually there if you open the file
TTT t = new TTT("Somebody once told me", System.currentTimeMillis());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] allBytes;
try {
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(t);
os.flush();
allBytes = bos.toByteArray();
} finally { try { bos.close(); } catch (IOException ex) {} }
out.put(allBytes);
memoryMappedFile.close();
out.clear();
}
}
class TTT implements Serializable {
public String s;
public long a;
public TTT(String s, long a) {
this.s = s;
this.a = a;
}
}
I think that the answer is No.
In Linux, the Java Watch Service API is implemented using
inotify(7), and memory mapped files are implemented usingmmap(2).The manual entry for inotify says this in the limitations section: