2015-11-17 15 views
5

Tôi thấy một hành vi lạ (không chắc chắn đây là hành vi mong đợi) bằng cách sử dụng java.nio.file.WatchService .Dịch vụ xem Java NIO đã tạo cả 'ENTRY_CREATE' và 'ENTRY_MODIFY' khi một Tệp mới được thêm vào thư mục đồng hồ

Vấn đề là tôi có thư mục được đăng ký với WatchService. Khi tôi sao chép một tập tin mới vào thư mục này, sau đó hai WatchEvent được tạo, một trong mỗi cho:

'ENTRY_CREATE' và 'ENTRY_MODIFY'.

Theo như tôi hiểu, một tệp mới (được sao chép từ thư mục khác không được theo dõi) phải tạo chỉ một sự kiện, tức là: 'ENTRY_CREATE'.

Ai đó có thể giải thích lý do sự kiện bổ sung 'ENTRY_MODIFY' được tạo?

Mã của tôi:

public void watch() { 
    WatchKey key = watcher.poll(); 

    //log.info("Watcher scheduler running. Watch key {}", key.hashCode()); 

    if (key != null) { 
     Workflow workflow = keys.get(key); 
     log.info("Runing watcher for key '{}' and workflow {}", key.hashCode(), workflow.getName()); 
     File hotFolder = new File(workflow.getFolderPath()); 
     Path dir = hotFolder.toPath(); 

     for (WatchEvent<?> event : key.pollEvents()) { 
      WatchEvent<Path> ev = cast(event); 
      Path name = ev.context(); 
      Path child = dir.resolve(name); 

      log.info("Polling event for name {} and child {} and dir {}", name.toFile(), child.toFile(), dir.toFile()); 

      if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) 
       continue; 

      try { 
       switch (event.kind().name()) { 
       case "ENTRY_CREATE": 
        log.info("New file {}", child.toFile()); 
        fileService.processNewFile(child.toFile(), workflow); 
        break; 
       case "ENTRY_MODIFY": 
        log.info("File modified.... {}", child.toFile()); 
        fileService.processModifiedFile(child.toFile(), 
          workflow); 
        break; 
       default: 
        log.error("Unknown event {} for file {}", event.kind() 
          .name(), child.toFile()); 
        break; 
       } 
       // Operation op = Operation.from(event.kind()); 
       // if (op != null) 
       // publisher.publishEvent(new FileEvent(child.toFile(), 
       // workflow, op)); 
      } catch (Throwable t) { 
       log.warn("Error while procesing file event", t); 
      } 
     } 

     key.reset(); 
    } 
} 

Vì vậy, khi tôi sao chép một tập tin, nói name = "abc.txt", các bản ghi hiển thị:
New file abc.txt
tập tin sửa đổi .... abc .txt


Mọi yếu tố đầu vào đều được trưng cầu cao.

Trả lời

4

Kiểm tra phần "Phụ thuộc nền tảng" trong WatchService JavaDoc.

Trình theo dõi hoạt động chính xác trong trường hợp bạn mô tả. Và nói đúng, khi bạn sao chép một tệp vào một thư mục, các tệp thực sự là CREATED và sau đó được sửa đổi.

Có rất nhiều điều cần xem xét khi sử dụng một WatcherService, hành vi của nó thay đổi rất nhiều với ví dụ:

Hệ điều hành
  • cổ phiếu
  • đĩa được mã hóa
  • Mạng
  • ...
3

Tôi nghĩ, câu hỏi đã được trả lời ở đây.

Ví dụ Java: WatchService gets informed before content is copied

Trong hai từ, các sự kiện được tạo ra bởi hệ thống hoạt động của bạn. Bạn đã có hai sự kiện có nghĩa là hệ điều hành của bạn thực hiện sao chép theo cách không nguyên tử. Nếu bạn cố gắng đọc tệp ở đâu đó giữa ENTRY_CREATE và ENTRY_MODIFY, tệp sẽ không nhất quán. Nhưng một lần nữa, nó phụ thuộc vào hệ điều hành của bạn. Ví dụ trên Windows 7 tôi nhận được ENTRY_CREATE một lần và ENTRY_MODIFY hai lần cho các tệp lớn. Vì vậy, bạn thực sự không thể chắc chắn liệu tệp có được sao chép thành công hay không, bạn phải đưa ra các chỉ số phụ thuộc vào ứng dụng/HĐH.

Các vấn đề liên quan