I have to read some information from files as soon as they're created in a directory. These files are created automatically by another program. For that, I'm using the WatchService
to watch for file creation, and Scanner
to read the file. On the main method, I have a simple while(true)
, and my Watcher
class is called. This is the constructor:
public Watcher(String srcDir, String targetDir) throws IOException, InterruptedException {
this.srcDir = Paths.get(srcDir);
this.targetDir = Paths.get(targetDir);
this.watcher = this.srcDir.getFileSystem().newWatchService();
this.srcDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE); // this will check ONLY for new files; no
// deletions or modifications
this.key = this.watcher.take();
}
And the method called in the main loop (I removed part of the code because it's not relevant):
public void checkForNewFile() throws IOException {
String[] info = new String[6];
if (this.watcher != null) {
List<WatchEvent<?>> events = this.key.pollEvents();
newFileName = "";
for (WatchEvent event : events) {
// I kept getting errors when trying to get only the last event
newFileName = event.context().toString();
}
if(newFileName != "") {
System.out.println("opening new file...");
Scanner scanner = new Scanner(new FileInputStream(srcDir.toString() + "/" + newFileName));
String line;
System.out.println(scanner.hasNext());
while(scanner.hasNext()) {
line = scanner.nextLine();
System.out.println("splitting lines...");
String[] parts = line.split("|");
...
}
scanner.close();
}
this.key.reset();
}
}
In the method above, when I run the program normally, System.out.println(scanner.hasNext());
returns false and the while
loop never happens, but when debugging, the code works fine.
I know this points to threading issues, but I'm not explicitly creating any threads, and this project doesn't even need multiple threads. Am I doing something wrong? What can I do to allow this code to work correctly?
I would guess, that your code reads a newly generated file, where the content is not flushed yet and therefor is no line. In debug there is more time for the thread writing the file and flush it.
Perhaps you can play around with file locks to get rid of this problem.