Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
456 views
in Technique[技术] by (71.8m points)

windows - Java: WatchService gets informed before content is copied

I've tried to copy&paste a very small file into a folder which is observed by a watch service. The first time works great, but on all following copy&paste actions, i get an exception that another process handles the file already. With experiments I've found out that my service is informed when Windows creates the file and not when its content is copied. If I lock the file, Windows isn't able to copy any data and the file is empty. On the other hand, if I move the file into the directory, everything works fine.

Is that a bug from Windows? I wasn't able to test it on a mac or Linux workstation. Or maybe it was just me being incapable. Any help is appreciated.

My code looks like the following:

try (WatchService watchService = importPath.getFileSystem().newWatchService()) {
  importPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
  handleExistingFiles();

  try {
    do {
      WatchKey watchKey = watchService.take();
      if (!watchKey.isValid()) {
        continue;
      }

      boolean hasCreationEvents = false;
      for (WatchEvent<?> event : watchKey.pollEvents()) {
        hasCreationEvents |= event.kind().equals(StandardWatchEventKinds.ENTRY_CREATE);
      }
      watchKey.reset();

      if (hasCreationEvents) {
        handleNewFiles();
      }
    }
    while (!Thread.currentThread().isInterrupted());
  }
  catch (InterruptedException ignoredEx) {
    Thread.currentThread().interrupt();
  }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The copy operation is not always atomic.

With atomic copy (or move) you will get a single ENTRY_CREATE event and the file referenced by the event will be complete and available for reading.

If the copy is not atomic, you will receive an ENTRY_CREATE event when the file is created and then you will receive one or more ENTRY_MODIFY events while the file is being written by the copy operation.

There is no easy way to determine when the copy operation has finished writing to a file and released it. Depending on the OS and file system you could get FileNotFoundException when trying to open a file for reading while it is locked by the copy operation or you could successfully open a file but you will get partial contents when you actually read it.

You will have to implement some heuristics like trying to read a file immediately after ENTRY_CREATE and rescheduling the reading for some later time if the initial reading failed.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...