Dan*_*ger 5 .net c# compare file winforms
背景
我正在开发一个简单的 Windows 服务,它监视某些目录的文件创建事件并记录这些事件 - 长话短说,以确定文件是否从目录 A复制到目录 B。如果 X 时间后文件不在目录 B 中,将发出警报。
问题是我只有在确定文件是否已进入目录 B 时才能继续获取信息 - 我假设两个具有相同名称的文件是相同的,但是因为有超过 60 个目录 A和单个目录 B - 并且任何目录 A 中的文件可能会意外地与另一个目录相同(按日期或顺序),这不是一个安全的假设......
例子
假设,例如,我在目录 C:\Test 中存储了一个文件“E17999_XXX_2111.txt”的日志。我将存储此文件的文件名、文件路径、文件创建日期、文件长度和 BOM。
30 秒后,我检测到在目录 C:\FinalDestination 中创建了文件“E17999_XXX_2111.txt”...现在我有确定是否的任务;
a) 该文件与在 C:\Test 中创建的文件相同,因此我可以将第一个日志更新为完整并且不再担心它。
b)文件不一样,我不知何故错过了前面的步骤 - 因此我可以忽略这个文件,因为它已经找到了通往目标目录的路。
研究
因此,为了确定在目标中创建的文件是否与在第一个实例中创建的文件完全相同,我进行了一些研究并找到了以下选项:
a) 文件名比较
b) 长度比较
c) 创建日期比较
d) 逐字节比较
e) 哈希比较
问题
a) 正如我上面所说,单独使用文件名太冒昧了。
b) 同样,仅仅因为文件内容的长度相同,并不一定意味着文件实际上相同。
c) 问题在于复制的文件在技术上是一个新文件,因此创建日期会发生变化。无论出现在目录 A 和目录 B 中的文件之间经过的时间如何,我都希望将第一个日志设置为完整。
d) 除了这种方法非常慢这一事实之外,如果第二个文件以某种方式改变了编码,似乎还有一个问题——例如在 ANSII 和 ASCII 之间,这会导致像 ascii 引号这样的东西的字节不匹配
我不想假设仅仅因为 ASCII ' 已更改为 ANSII ',文件现在不同,因为它几乎相同。
e)这似乎与逐字节比较具有相同的缺点
编辑
看来我遇到的实际问题归结为目录之间编码差异的原因 - 我目前无法访问处理这部分的代码,所以我不知道为什么会发生这种情况,但我我正在寻找一种解决方案,该解决方案可以比较文件而不管编码如何,以确定“真正的”差异(即不是那些由于编码而改变字节的差异)
解决方案
如果@Magnus 建议的初始比较因此未能找到匹配项,则在对我的文件进行编码以删除任何错误数据后,我现在已经设法通过使用下面的 SequenceEqual 比较来解决此问题。代码如下:
byte[] bytes1 = Encoding.Convert(Encoding.GetEncoding(1252), Encoding.ASCII, Encoding.GetEncoding(1252).GetBytes(File.ReadAllText(FilePath)));
byte[] bytes2 = Encoding.Convert(Encoding.GetEncoding(1252), Encoding.ASCII, Encoding.GetEncoding(1252).GetBytes(File.ReadAllText(FilePath)));
if (Encoding.ASCII.GetChars(bytes1).SequenceEqual(Encoding.ASCII.GetChars(bytes2)))
{
//matched!
}
Run Code Online (Sandbox Code Playgroud)
谢谢您的帮助!
然后,您必须比较文件中的字符串内容。的StreamReader(其ReadLines用途)应检测的编码。
var areEquals = System.IO.File.ReadLines("c:\\file1.txt").SequenceEqual(
System.IO.File.ReadLines("c:\\file2.txt"));
Run Code Online (Sandbox Code Playgroud)
注意ReadLines不会将完整的文件读入内存。