0

You have:

A process (READER) that opens a text file (TEXTFILE), reads all the lines until the EOF and waits for new lines to appear.

The READER is implemented in Java and the waiting part uses java.nio.file.WatchService, which if I understand correctly on Linux uses inotify. I am not sure which is more relevant to the question. The implementation is quite simple (exception handling and some ifs left out for brevity):

 WatchService watcher;
 watcher = FileSystems.getDefault().newWatchService();
 Path logFolder = Paths.get("/p/a/t/h");
 logFolder.register(watcher, ENTRY_MODIFY);

 reader = Files.newBufferedReader("TEXTFILE", Charset.forName("US-ASCII"));
 key = watchService.take();

 for (WatchEvent<?> event : key.pollEvents()) {
     WatchEvent.Kind<?> kind = event.kind();

     doSomethingWithTheNewLine(reader.readLine());
 }

Now, if I run READER and

  1. Open TEXTFILE in an editor, add a line and save it, the result is that the READER doesn't seem to get the new line

  2. If, on the other hand, I do something like this in bash

while true; do echo $(date) ; sleep 2; done >> TEXTFILE

then the READER does get the new lines

EDIT: As far as I can see, the difference here that may matter is that in the first case, the editor loads the content of the file, closes it (I assume), and on saving it opens the file again and synchronizes the content with the file system, while the bash line keeps the file opened... how would that make any difference, I am not sure

I suppose the simple question is why???

They way I understood scenario like this is that Linux is using some sort of locking when >1 processes need access to the same file on filesystem at the same time. I also thought that when a process A opens a file descriptor to a file at time t0, it gets let's say a snapshot of what the file content was at t0. Even if the process A doesn't close the file descriptor (which is what seems to be the case here) and a process B appends to that file at some tome t0 + delta, then the process A would have to reopen the file descriptor to see the changes, it cannot hold to the same file descriptor and get new data being appended to that file... though it's obvious that what I've observed contradicts that assumption....

artur
  • 1,710
  • 1
  • 13
  • 28
  • More than likely, you don't see the updated lines from the editor because the editor creates an entirely new file that just has the same name as the old file - the old one gets unlinked. – Andrew Henle Apr 10 '17 at 10:04
  • @AndrewHenle that's exactly what is happening! I was using vim and educated myself on the save/write modes here http://unix.stackexchange.com/questions/36467/why-inode-value-changes-when-we-edit-in-vi-editor. When I forced vim to reuse the existing file, I can see the updates. Thanks very much. If you post this as an answer, I will happily accept it. Now, that obviously means that I don't understand how reading from a file descriptor works when there's another process writing to that same file. Any useful links, or something I can enlighten myself with? Thanks again! – artur Apr 10 '17 at 10:35
  • I've learnt something today! Kind of half guessing from here http://stackoverflow.com/questions/5284062/two-file-descriptors-to-same-file, I guess what happens is, when two processes open the same file with `open` they get two file descriptors with their own read/write offsets. The whole 'snapshot' theory I came up with is BS. If process A has a FD opened to a file T and its read counter is at the EOF, then if process B appends to that file and process A is notified about the change by `inotify` then if process A starts reading from T it will get the data written by B.That how it SEEMS to work – artur Apr 10 '17 at 14:17
  • I am not even sure how file locking comes to play here. Ignorance is bliss :) – artur Apr 10 '17 at 14:25

0 Answers0