2012-09-07 22 views
6

Khi thư mục được theo dõi bởi WatchService bị xóa, thư mục chính của thư mục đó không phản ánh ngay lập tức xóa tệp trong phương thức listFiles của Tệp và không thể bị xóa. Cho đến khi toàn bộ dịch vụ rõ ràng là stopped hậu quả đối với phụ huynh có vẻ như:Dịch vụ xem Java xuất hiện để tạo lại các tệp đã xóa. Chuyện gì vậy?

  1. recommended recursive solution để xóa thư mục không trống.
  2. deleteOnExit không được thực hiện khi chấm dứt thông thường
  3. Gọi tới delete trả về sai và không ảnh hưởng đến hệ thống tệp.

Để chứng minh, mã kiểm tra này:

import java.io.*; 
import java.nio.file.*; 

class DirectoryTester { 
    static WatchService watcher; 
    static { 
    try{watcher = FileSystems.getDefault().newWatchService();} 
    catch (IOException e) {e.printStackTrace();} 
    } 

    public static void main(String[] args) throws IOException { 
    String SEPARATE = System.getProperty("file.separator"); 
    String testDirName = System.getProperty("user.dir") + SEPARATE + "testDir"; 
    String subDirName = testDirName + SEPARATE + "subDir"; 
    String fileName = subDirName + SEPARATE +"aFile"; 
    create(fileName); 
    Paths.get(subDirName).register(watcher, StandardWatchEventKinds.ENTRY_DELETE); 
    delete(new File(testDirName)); 
    } 

    static void create(String nameOfFile) throws IOException { 
    new File(nameOfFile).getParentFile().mkdirs(); 
    Files.createFile(Paths.get(nameOfFile)); 
    System.out.println("Created " + nameOfFile); 
    }  

    static void delete(File toDelete) throws IOException { 
    if (toDelete.isDirectory()) 
     for (File c : toDelete.listFiles()) 
     delete(c); 
    int numContainedFiles = toDelete.listFiles() != null ? toDelete.listFiles().length : 0; 
    if (!toDelete.delete()) { 
     System.out.println("Failed to delete " + toDelete + " containing " + numContainedFiles); 
    } 
    else { 
     System.out.println("Deleted " + toDelete + " containing " + numContainedFiles); 
    } 
    } 
} 

cung cấp cho các đầu ra sau trên cửa sổ, tương ứng với testDir không được xóa trên hệ thống tập tin.

Created C:\Dropbox\CodeSpace\JavaTestbed\src\testDir\subDir\aFile 
Deleted C:\Dropbox\CodeSpace\JavaTestbed\src\testDir\subDir\aFile containing 0 
Deleted C:\Dropbox\CodeSpace\JavaTestbed\src\testDir\subDir containing 0 
Failed to delete C:\Dropbox\CodeSpace\JavaTestbed\src\testDir containing 1 

Nếu tôi đặt điểm ngắt sau khi xóa subDir Tôi có thể thấy rằng nó đã thực sự bị xóa trên hệ thống tệp. Tiếp tục từ điểm ngắt làm cho lần xóa cuối cùng thành công, cho thấy rằng đây có thể là vấn đề với khả năng hiển thị các thay đổi được thực hiện bởi chuỗi dịch vụ đồng hồ. Có ai biết chuyện gì đang xảy ra ở đây không, và nếu đó là lỗi? Những gì tôi thực sự cố gắng làm là xóa các thư mục được giám sát mà không dừng giám sát trên các thư mục khác, cho rằng dường như không có phương thức đường dẫn chưa đăng ký được cung cấp bởi API Java là cách nào khác để hoàn thành điều này?

+0

Tôi tự hỏi đây có phải là vấn đề chỉ dành cho Windows – Pyrolistical

+1

Hành vi tương tự ở đây không. Thêm một 'Thread.sleep (100);' trong chính trước khi gọi 'delete (new File (testDirName));' giải quyết vấn đề - lạ ... – assylias

Trả lời

7

có thể liên quan:

http://bugs.sun.com/view_bug.do?bug_id=6972833

Các WatchService có một tay cầm mở cửa cho mỗi thư mục theo dõi. Nếu một thư mục đồng hồ bị xóa thì WatchService sẽ đóng trình điều khiển để mục nhập thư mục có thể bị xóa khỏi thư mục chính. Một vấn đề phát sinh đối với các tiện ích và ứng dụng mong muốn có thể xóa thư mục cha ngay lập tức vì nó có thể mất một vài phần nghìn giây để dịch vụ đồng hồ nhận được thông báo và đóng xử lý. Nếu trong thời gian đó công cụ cố gắng xóa thư mục mẹ thì nó sẽ thất bại. Chúng tôi không có giải pháp cho vấn đề này vào lúc này.

+0

+1 Có vẻ chính xác điều đó. – assylias

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