2011-06-03 80 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会这样做)。