2010-08-28 56 views
3

我有兩個硬盤卷(一個是另一個的備份映像),我想比較卷並列出所有已修改的文件,以便用戶可以選擇他/她想要回滾的卷。如何比較2個卷和列出修改後的文件?

目前,我通過新卷遞歸併將每個文件的時間戳與舊卷的文件(如果它們是int舊的卷)進行比較。顯然這是一個失誤的方法。這是費時和錯誤的!

有沒有一種有效的方法來做到這一點?

編輯:
- 我使用FindFirstFile並喜歡遞歸音量,並收集每個文件的信息(不是很慢,只是幾分鐘)。
- 我正在使用卷影複製進行備份。
- 備份卷是遠程的,因此我無法連續監視實際卷。

+1

爲了獲得更有用的答案,您應該在您的工具應運行的平臺下添加。 POSIX,win32還是別的?不同的平臺具有不同的文件系統語義。 – maxschlepzig 2010-08-28 18:16:01

+0

對不起,現在添加了win32標籤。謝謝 – lalli 2010-08-28 18:22:36

+0

耗時? *你如何*通過卷遞歸和比較事物?我希望不是手動的。你熟悉腳本語言嗎? Perl的?校驗? – Beta 2010-08-28 18:25:45

回答

2

這部分取決於兩個卷如何重複;如果它們是從文件系統的角度來看是「真實」的副本(例如,卷影副本或其他塊級副本),您可以就USN做一些棘手的小事情,這是其他人建議您研究的一般技術。例如,您可能想要查看像FSCTL_READ_FILE_USN_DATA這樣的API。該API可讓您比較文件的兩個不同副本(同樣,假設它們是具有相同文件,並且具有與塊級備份相同的文件參考號)。如果你想在很大程度上無國籍,這個和類似的API會在這裏幫助你很多。我的算法將是這個樣子:

foreach(file in backup_volume) { 
    file_still_exists = try_open_by_id(modified_volume) 
    if (file_still_exists) { 
     usn_result = compare_usn_values_of_files(file, file_in_modified_volume) 
     if (usn_result == equal_to) { 
      // file hasn't changed at all 
     } else { 
      // file has changed (somehow) 
     } 
    } else { 
     // file was deleted (possibly deleted and recreated) 
    } 
} 
// we still don't know about files new in modified_volume 

所有這麼說,我的經歷使我相信,這將是比我現成的,袖口的說明提示更加複雜。不過,這可能是一個很好的起點。

如果卷不是彼此的塊級副本,那麼比較USN號碼和文件ID(如果不是不可能的話)將是非常困難的。相反,如果不打開每個文件都不是不可能的,那麼很可能會按文件名進行操作(時間可以通過應用程序進行修改,大小和時間可以在findfirst/next查詢中過時,而您必須處理已刪除然後重新創建的案例,重命名案例等)。

因此,知道你對環境有多少控制是非常重要的。

+0

我在這個方法上鬆散地前進。謝了哥們! – lalli 2010-08-30 03:38:54

0

假設您沒有將新捲上的每個文件與快照中的每個文件進行比較,那麼這是您唯一可以做到的方法。如果沒有查看所有文件,你將如何查找哪些文件未被修改?

+0

這是我已經切換到的方法(我用舊快照對新卷中的每個文件進行比較),但這非常緩慢。 我在想也許是在較低的層次上(掃描和比較塊或其他東西?) – lalli 2010-08-28 18:14:27

+1

@lalli:沒有比FindFirstFile和朋友更低的API(支持)。即使你打算通過自己解析磁盤格式的NTFS來做到這一點,我懷疑你可以做得比Windows自己的ntfs.sys更快。 – 2010-08-28 19:30:57

0

我不是Windows程序員。 但是不應該有stat函數來檢索文件的修改時間。 根據模時間對文件進行排序。 mod時間大於上次備份時間的文件是您感興趣的文件。

你第一次可以遍歷備份捲來找出最大模時間和創建時間從你感興趣的設置。 我假設感興趣的目錄不會在備份卷中被修改。

+0

'stat'不是Windows功能。 – 2010-08-28 19:29:55

+0

不應該GetFileTime做這項工作。另外你甚至不需要排序,如果你知道最大模時間。 U可以在當前音量的單個傳遞中獲得列表。 – aeh 2010-08-28 23:11:55

+0

@ user433874:否,'GetFileTime'需要一個文件句柄,這意味着您必須打開每個有問題的文件。 'FindFirstFile'和朋友**已經在枚舉一個目錄時返回時間**,所以我真的不明白你的意思。 – 2010-08-28 23:43:07

1

與其等待,直到變化發生後,然後掃描整個磁盤發現已更改的(通常是幾個)的文件,我想建立一個程序使用ReadDirectoryChangesW監測變化他們發生。這可以讓你用最少的麻煩和麻煩建立一個文件列表。

+0

請注意,這不適用於重新啓動或其他此類樂趣。另外,當卷影複製播放時,它可能會導致有趣的結果。如果像這樣的解決方案是可以接受的,則應考慮使用Usn日記(http://msdn.microsoft.com/zh-cn/library/aa363798.aspx)。 – 2010-08-28 20:07:35

+0

@比利:是的,我認爲如果你打算這樣做,你可能會實現它作爲服務自動啓動。我毫不猶豫地推薦USN期刊,僅僅因爲我從來沒有使用它,但從我記憶中的文檔來看,這可能是一個不錯的選擇。 – 2010-08-28 20:17:53

+0

@Jerry:問題是,即使您註冊自動啓動,您也無法及早啓動以捕獲由內核所做的更改。在任何情況下,任何基於監控的解決方案都不會在重啓後100%可靠。 – 2010-08-28 20:32:46

0

不知道你想要在這裏做什麼的更多細節,這很難說。但是,你想什麼,我想一些技巧來實現:

  • 如果你只關心NTFS捲上,我建議尋找到USN /更改日誌API的。他們自2000年以來一直存在。通過這種方式,在初始庫存之後,您只能查看此時的變化。這是一個很好的起點,儘管這裏有一篇非常古老的文章:http://www.microsoft.com/msj/0999/journal/journal.aspx
  • 此外,利用USN API,您可以省略散列步驟,只需記錄日誌中的信息(這會在/ if時變得更清晰你看看所說的API)
  • 第一次通過比較驅動器的內容,使用散列,如SHA-1或MD5。
  • 將散列和其他此類信息存儲在某種數據庫中。例如,SQLite3。請注意,這可能佔用大量的空間本身。快速查看帶有40k +文件的音頻文件夾將導致大約750兆字節的MD5信息。
+0

捲上每個文件的MD5散列可能會相當大 - 計劃爲您的索引提供幾GB的空間。 – 2010-08-28 20:12:51