2014-04-09 24 views
5

Tôi đã cố gắng sao chép & dán một tệp rất nhỏ vào một thư mục được dịch vụ xem theo dõi. Lần đầu tiên hoạt động tốt, nhưng trên tất cả các thao tác dán & sau đây, tôi nhận được ngoại lệ là một quy trình khác xử lý tệp đó. Với các thử nghiệm tôi đã phát hiện ra rằng dịch vụ của tôi được thông báo khi Windows tạo tệp và không phải khi nội dung của nó được sao chép. Nếu tôi khóa tệp, Windows không thể sao chép bất kỳ dữ liệu nào và tệp này trống. Mặt khác, nếu tôi di chuyển tệp vào thư mục, mọi thứ sẽ hoạt động tốt.Java: WatchService được thông báo trước khi nội dung được sao chép

Đó có phải là lỗi từ Windows không? Tôi đã không thể kiểm tra nó trên một máy trạm mac hoặc Linux. Hoặc có lẽ đó chỉ là tôi không có khả năng. Bất kỳ trợ giúp được đánh giá cao.

Mã của tôi trông giống như sau:

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(); 
    } 
} 
+0

Và (các) chương trình nào tạo tệp mà bạn xem? Đừng quên rằng thường xuyên hơn không, chương trình ghi vào một tập tin tạm thời và _only then_ ghi đè lên bản gốc – fge

+0

Đó là một chương trình cũ của chúng ta tạo ra một tập tin đầu ra để truyền dữ liệu đến hiện tại. Tôi sẽ kiểm tra xem các tập tin được viết như thế nào, nhưng như Oleg được đề cập dưới đây, nó chỉ có thể là một vấn đề mà hai sự kiện xảy ra, một cho việc tạo và một cho sửa đổi và tôi trả lời sai ... – Teazl

Trả lời

6

hoạt động Bản sao không phải lúc nào cũng nguyên tử.

Với bản sao nguyên tử (hoặc di chuyển), bạn sẽ nhận được một sự kiện ENTRY_CREATE duy nhất và tệp được tham chiếu bởi sự kiện sẽ hoàn thành và có sẵn để đọc.

Nếu bản sao không phải là nguyên tử, bạn sẽ nhận được sự kiện ENTRY_CREATE khi tệp được tạo và sau đó bạn sẽ nhận được một hoặc nhiều sự kiện ENTRY_MODIFY trong khi tệp đang được tác vụ sao chép ghi.

Không có cách nào dễ dàng để xác định thời điểm hoạt động sao chép đã hoàn tất ghi vào một tệp và phát hành tệp đó. Tùy thuộc vào hệ điều hành và tập tin hệ thống bạn có thể nhận được FileNotFoundException khi cố gắng mở một tệp để đọc trong khi nó bị khóa bởi thao tác sao chép hoặc bạn có thể mở tệp thành công nhưng bạn sẽ nhận được một phần nội dung khi bạn thực sự đọc nó.

Bạn sẽ phải triển khai một số chẩn đoán như cố gắng đọc tệp ngay sau ENTRY_CREATE và lên lịch lại đọc cho một số lần sau nếu đọc ban đầu không thành công.

+0

Cảm ơn gợi ý . Tôi đã thay đổi mã từ ENTRY_CREATE thành ENTRY_MODIFY và không gặp vấn đề gì, ít nhất là với các cửa sổ. Tôi sẽ kiểm tra nó với các hệ điều hành khác và hy vọng rằng nó sẽ làm việc ở đó. Sau khi tôi đã xử lý tệp, tệp đó sẽ bị xóa. Tôi đoán rằng sẽ làm các trick :) – Teazl

+0

Tôi đã có thể kiểm tra nó trên một hệ thống MAC. Nó cũng hoạt động ở đó. Cảm ơn rất nhiều! * yay * – Teazl

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