2011-06-03 111 views
4

我們需要比較兩個(或更多)文本文件的內容,以確定是否需要創建備份。如果它們不同,我們創建一個新的備份。delphi比較文本文件內容

我目前使用每個文件的CRC值來檢查差異,但我想知道是否有更有效或優雅的方式來檢測文件之間的差異。

//Use madZIP to calculate the CRC fior this file 
GetUncompressedFileInfo(Filename_1, Size_1, NewCRC); 

//Use madZIP to calculate the CRC fior this file 
GetUncompressedFileInfo(Filename_2, Size_2, OldCRC); 

//if ThisFileHash = ExistingFileHash then 
if (OldCRC <> NewCRC) then 
    CreateABackup; 

問候,彼得。

+3

唯一的事情就是檢查大小,如果大小不同,那麼文件也是如此。它是一個簡單但快速的預檢,你可以加快速度,如果大小不同,不要打擾做CRC校驗。 – BugFinder 2011-06-03 11:15:13

+1

您認爲您對CRC解決方案的效率和優雅性究竟如何? – jpfollenius 2011-06-03 12:02:16

+0

我正在重寫現有解決方案,並正在尋找改進現有代碼的方法。我並不是說CRC是無效的,但是可能有另一種方式來獲得滿足我需求的相同結果。 – 2011-06-03 14:53:11

回答

2

CRC可能更準確,而且效率很高。但是你需要檢查內容嗎?

我假設您正在檢查CRC以查看是否進行了修改並重新備份更新的文件。在這種情況下,FileAge()會很好。

+0

是的。如果內容已更改,我們只想進行備份。 – 2011-06-03 11:14:34

+1

就像BugFinder那樣。 CRC之前的FileSize大部分時間應該可以節省一些工作量。否則CRC是我知道實際比較內容的最有效的方法。 – JamesT 2011-06-03 11:21:44

+0

有關快速高效的CRC例程的任何建議? – 2011-06-03 11:39:46

7

CRC不是檢測文件更改的安全方法 - 密碼哈希(如MD5或SHA1)要好得多。

另一種方法(如構建系統使用的方法)是比較文件日期。如果該文件比備份更新,則需要新的備份。

+0

爲此,不需要密碼安全哈希。這只是一個備份場景。 – 2011-06-03 11:24:16

+0

@ba__friend:CRC有較高的誤報機率,可以說兩個文件是相同的,即使它們不是。最安全的方法是比較上次更改的日期和時間以及具有足夠位數的散列,以確保較小的碰撞機率。 128,256或事件512位散列。實際上幾乎所有好的備份和其他類似的SW都以這種方式工作。 – Runner 2011-06-03 11:36:14

+3

+1針對CRC誤報,這可能是備份場景的問題。但是,文件日期可能會導致錯誤的否定,因爲我發現有時使用NTFS,FileAge可能會根據夏令時時區返回一小時更改... – 2011-06-03 11:57:19

0

實際上,爲了保證文件身份最好的做法是存儲內容散列(例如:CRC-32或任何其它散列函數)文件大小。這樣做可以提高可靠性。 RE:存儲 - 不需要計算已知不變的內容的哈希值。

1

您還應該考慮使用增量備份。

我已經爲我們的SynProject開源工具發佈了一些優化的文件版本控制功能。 類,在ProjectVersioning單位允許在一個zip容器內的二進制比較存儲。

我們專有的但比zip快的SynLZ algorithm用於存儲增量差異。它在練習中效果很好。

參見例如TVersions.FillStrings檢索要更新的文件列表的方法。

請注意,根據當前的夏令時,您可能會發現一小時的差異。以下是我們如何允許進行日期比較:

function SameFileDateWindows(FileDate1,FileDate2: integer): boolean; 
// we allow an exact one Hour round (NTFS bug on summer time zone change) 
begin 
    dec(FileDate1,FileDate2); 
    result := (FileDate1=0) or (FileDate1=1 shl 11) or (FileDate1=-(1 shl 11)); 
end; 

我們在此處不會閱讀文件內容。爲了備份目的,依靠文件日期來標記要比較的文件就足夠了。然後執行差分比較關於這兩個版本的文件。如果文件內容相同,它將只存儲日期差異。

恕我直言,你不應該使用專有的madzip容器,而是一個標準的,如.zip。有幾個,包括SynProject或我們的ORM中使用的我們的版本。它比MadZip更快並且解壓縮處於優化模式。請參閱用於低級別壓縮的SynZip單元和一個簡單的.zip讀取器和寫入器,以及SynZipFiles(用於SynProject)中的更多演變類。對於純粹的德爾福版本,比如madzip,請檢查比madzip更快的PasZip單元(但PasZip不會使用Unicode Delphi進行編譯,而SynZip會這樣做)。