2008-09-11 40 views
7

Trong Windows, có cách nào dễ dàng để biết liệu một thư mục có một tệp phụ đã thay đổi không?Cách xem một thư mục con của thư mục có thay đổi không

Tôi đã xác minh và ngày sửa đổi cuối cùng trên thư mục không được cập nhật khi tệp con thay đổi.

Có mục đăng ký nào tôi có thể đặt để sửa đổi hành vi này không?

Nếu vấn đề quan trọng, tôi đang sử dụng khối lượng NTFS.

Tôi cuối cùng muốn có khả năng này từ chương trình C++.

Quét toàn bộ thư mục đệ quy sẽ không hoạt động đối với tôi vì thư mục quá lớn.

Cập nhật: Tôi thực sự cần một cách để thực hiện việc này mà không cần quy trình chạy trong khi thay đổi xảy ra. Vì vậy, cài đặt một hệ thống tập tin watcher không phải là tối ưu cho tôi.

Update2: Bit lưu trữ cũng sẽ không hoạt động vì nó có cùng vấn đề với ngày sửa đổi cuối cùng. Bit lưu trữ của tệp sẽ được đặt, nhưng các thư mục sẽ không.

+0

Mặc dù không dễ dàng như việc bit lưu trữ được lật vào chính thư mục, nếu Windows không hỗ trợ tự động "cuộn lên" cờ lưu trữ ở cấp thư mục, hãy đọc cho đến khi bạn tìm thấy ít nhất một tệp (hoặc không có tệp nào) với cờ lưu trữ có thể là lựa chọn duy nhất của bạn, được đưa ra trên con bạn –

+0

Bạn có thể tạo một "Update3" giải thích tại sao Nhật ký NTFS không hoạt động cho bạn? –

+0

Vì tôi muốn truy cập nó qua mạng cũng như –

Trả lời

6

Điều này article sẽ giúp ích. Về cơ bản, bạn tạo một hoặc đối tượng thông báo hơn như:

 
HANDLE dwChangeHandles[2]; 
dwChangeHandles[0] = FindFirstChangeNotification( 
     lpDir,       // directory to watch 
     FALSE,       // do not watch subtree 
     FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes 

    if (dwChangeHandles[0] == INVALID_HANDLE_VALUE) 
    { 
    printf("\n ERROR: FindFirstChangeNotification function failed.\n"); 
    ExitProcess(GetLastError()); 
    } 

// Watch the subtree for directory creation and deletion. 
    dwChangeHandles[1] = FindFirstChangeNotification( 
     lpDrive,      // directory to watch 
     TRUE,       // watch the subtree 
     FILE_NOTIFY_CHANGE_DIR_NAME); // watch dir name changes 

    if (dwChangeHandles[1] == INVALID_HANDLE_VALUE) 
    { 
    printf("\n ERROR: FindFirstChangeNotification function failed.\n"); 
    ExitProcess(GetLastError()); 
    } 

và sau đó bạn chờ một thông báo:

 
while (TRUE) 
    { 
    // Wait for notification. 
     printf("\nWaiting for notification...\n"); 

     DWORD dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, 
     FALSE, INFINITE); 

     switch (dwWaitStatus) 
     { 
     case WAIT_OBJECT_0: 

     // A file was created, renamed, or deleted in the directory. 
     // Restart the notification. 
      if (FindNextChangeNotification(dwChangeHandles[0]) == FALSE) 
      { 
       printf("\n ERROR: FindNextChangeNotification function failed.\n"); 
       ExitProcess(GetLastError()); 
      } 
      break; 

     case WAIT_OBJECT_0 + 1: 

     // Restart the notification. 
      if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE) 
      { 
       printf("\n ERROR: FindNextChangeNotification function failed.\n"); 
       ExitProcess(GetLastError()); 
      } 
      break; 

     case WAIT_TIMEOUT: 

     // A time-out occurred. This would happen if some value other 
     // than INFINITE is used in the Wait call and no changes occur. 
     // In a single-threaded environment, you might not want an 
     // INFINITE wait. 

      printf("\nNo changes in the time-out period.\n"); 
      break; 

     default: 
      printf("\n ERROR: Unhandled dwWaitStatus.\n"); 
      ExitProcess(GetLastError()); 
      break; 
     } 
    } 
} 
+0

Tuy nhiên, đây không phải là những gì Brian yêu cầu; câu trả lời này không cung cấp giải pháp cho trường hợp một số tệp (trong thư mục) chỉ được sửa đổi (và không được đổi tên và không có thư mục con/tệp được tạo hoặc xóa). – tzot

+0

Nó phụ thuộc vào những gì bạn hiểu bằng cách sửa đổi. Nếu bạn có kế hoạch để duy trì một tấm gương của một thư mục, sau đó đổi tên chắc chắn nếu một sửa đổi. – botismarius

1

Nếu bạn không thể chạy quy trình khi thay đổi xảy ra, bạn không thể thực hiện nhiều thao tác ngoại trừ quét hệ thống tệp và kiểm tra ngày/giờ sửa đổi. Điều này yêu cầu bạn phải lưu trữ ngày/giờ cuối cùng của mỗi tệp và so sánh.

Bạn có thể tăng tốc độ này bằng cách sử dụng archive bit (mặc dù nó có thể làm hỏng phần mềm sao lưu của bạn, do đó hãy tiến hành cẩn thận).

Bit lưu trữ là thuộc tính tệp có trong nhiều hệ thống tệp máy tính, đáng chú ý là FAT, FAT32 và NTFS. Mục đích của bit lưu trữ là theo dõi thay đổi gia tăng đối với tệp cho mục đích sao lưu , còn được gọi là lưu trữ .

Như các bit lưu trữ là một bit nhị phân, nó là 1 hoặc 0, hoặc trong trường hợp này hơn thường được gọi là bộ (1) và rõ ràng (0). Hệ điều hành thiết lập bit lưu trữ bất kỳ khi nào tệp được tạo, di chuyển, đổi tên hoặc cách khác được sửa đổi theo bất kỳ cách nào. Do đó, bit lưu trữ đại diện cho một trong hai trạng thái : "đã thay đổi" và "không thay đổi" kể từ lần sao lưu cuối cùng.

Các bit lưu trữ không bị ảnh hưởng bởi chỉ cần đọc tệp. Khi tệp được sao chép là , bản lưu trữ của tệp gốc bit không bị ảnh hưởng, tuy nhiên, bit bản sao của bản sao sẽ được đặt tại thời điểm bản sao được tạo.

Vì vậy, quá trình này sẽ là:

  1. Xóa bit lưu trữ trên tất cả các file
  2. Hãy để thay đổi hệ thống tập tin theo thời gian
  3. Quét tất cả các tập tin - bất kỳ với bộ lưu trữ chút đã thay đổi

Điều này sẽ loại bỏ yêu cầu chương trình của bạn giữ trạng thái và vì bạn chỉ xem qua các mục nhập thư mục (trong đó bit được lưu trữ) và chúng được nhóm lại, nó phải rất, rất nhanh.

Nếu bạn có thể chạy một quá trình trong quá trình thay đổi, tuy nhiên, sau đó bạn sẽ muốn nhìn vào lớp FileSystemWatcher. Đây là một số example về cách bạn có thể sử dụng nó.

Nó cũng tồn tại trong .NET (đối với người tìm kiếm tương lai của loại hình này của vấn đề)

Có lẽ bạn có thể để lại một quá trình chạy trên máy tính này xem cho những thay đổi và tạo ra một tập tin cho bạn để đọc sau.

-Adam

+1

Tùy thuộc vào bản chất của ứng dụng của bạn, nó không nhất thiết phải là một ý tưởng tốt để đi xung quanh thay đổi các bit lưu trữ của các tập tin mà bạn không "sở hữu" ... – reuben

0

Nếu bạn không phản đối việc sử dụng .NET lớp FileSystemWatcher sẽ xử lý việc này cho bạn khá dễ dàng.

+0

bah. Đánh bại bởi Adam ... – NotMyself

0

Không có gì dễ dàng - nếu bạn có một ứng dụng đang chạy, bạn có thể sử dụng thông báo thay đổi tập tin Win32 apis (FindFirstChangeNotification) như được đề xuất với các câu trả lời khác. cảnh báo: circa 2000 xu hướng vi quét vi rút thời gian thực sẽ nhóm các thay đổi cùng nhau làm cho nó cần thiết để sử dụng bộ đệm thực sự lớn khi yêu cầu danh sách thay đổi hệ thống tập tin.

Nếu bạn không có ứng dụng đang chạy, bạn có thể bật nhật ký ntfs và quét tạp chí để thay đổi http://msdn.microsoft.com/en-us/library/aa363798(VS.85).aspx nhưng điều này có thể chậm hơn quét toàn bộ thư mục khi số lần thay đổi lớn hơn # tệp.

0

Từ bài gấp đôi so với một người nào đó nói: WMI Event Chìm

Vẫn đang tìm kiếm một câu trả lời tốt hơn mặc dù.

1

Có lẽ bạn có thể sử dụng thay đổi Journal NTFS 5 với DeviceIoControl như được giải thích here

2

ReadDirectoryChangesW

Một số mã mẫu tuyệt vời trong this CodeProject article

+0

Serge, mở rộng một chút đề xuất của bạn bằng ví dụ áp dụng cho câu hỏi. – tzot

+0

ΤΖΩΤΖΙΟΥ, tôi đã thêm liên kết vào bài viết CP rất tốt có chứa mã mẫu –

3

Đây có lẽ là quá mức cần thiết, nhưng IFS kit từ MS hoặc FDDK từ OSR có thể là một thay thế. Tạo trình điều khiển bộ lọc hệ thống tập tin của riêng bạn với việc giám sát đơn giản tất cả các thay đổi đối với hệ thống tập tin.

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