使用 StreamReader 和 Readline() 为文件生成 MD5 值

本文关键字:文件 MD5 StreamReader Readline 使用 | 更新日期: 2023-09-27 18:31:53

Ok. 我的问题的不同方面已经在这个论坛上被多次提出和回答。 但是,我认为我从未问过这个问题的特定变体。 所以,它来了。 我正在尝试为同一个文本文件生成两个哈希值,以便在处理之前和处理之后比较数据文件。 这点疯狂的目的是验证整个文件是否已被程序读取和处理。

我已经向自己证明,使用字节和数组然后将文件分解为大块,然后使用 MD5。TransformBlock 将创建一个具有价值(该程序代码遍布网络)。 而且,当我运行程序时,两个哈希值是相同的。 但是,我正在使用 StreamReader 的 readline() 方法一次读取一行文本文件,这会生成不正确的哈希值。

伪代码是:

BufferedStream reader = OpenFile(file)
string initialMd5 = generateMd5FromBufferedStream(reader)
//Start from the beginning again
reader.setposition = 0
reader.DiscardBufferedData();
while((tmpLine = reader.readline()) != null ) {
    Byte() buffer = GetBytes(tmpLine);
    md5.TransformBlock(buffer, 0, buffer.length, 0)
}
md5.TransformFinal(buffer, 0, 0);
String finalMd5 = ConvertToString(md5.Hash());

有什么想法吗? 我对如何解决问题没有想法了。

提前感谢!!

使用 StreamReader 和 Readline() 为文件生成 MD5 值

这不是所发布问题的答案,但检查文件的上次访问或修改日期以检测更改是不够的吗? .Net 在 System.IO 命名空间中有一个 FileInfo 类,其中包含 LastAccessTime 和 LastWriteTime 的属性。

因此,正如我在原始帖子中指出的那样,原因,使用 readline 创建哈希的原因,以便我可以在读取和处理文件时生成哈希。 这个想法是,如果读取和处理文件后的哈希与原始哈希相同,那么我可以确信整个文件已被处理。

我们遇到了 StreamReader.ReadLine() 没有读取整个文件的情况。 出于某种原因,它只是在文件的中间切断。 不过,这种行为是随机的。 而且,更糟糕的是,没有提出任何错误! 嘶!

无论如何,我的问题的答案是,当readline方法将字节数组(即文件中的一行文本)转换为字符串时,它会从字节数组中添加和减去"stuff"以执行转换。 因此,经过大量研究工作,答案似乎是在使用StreamReader.ReadLine读取文件时无法生成准确的哈希。

现在,如果有人对为什么愚蠢的东西停止读取中间的文件有任何想法......

这是我们目前正在使用的。

用法:

using (StreamReader file = new StreamReader(filepath))
{
    // store checksum
    Checksum = file.BaseStream.ToMD5Hash(); 
    ....
}

扩展方法:

public static string ToMD5Hash(this System.IO.Stream stream)
{
    string hash = string.Empty;
    long position = stream.Position;
    // Initialize a hash object
    using (System.Security.Cryptography.MD5 myHasher = System.Security.Cryptography.MD5.Create())
    {
        // Be sure it's positioned to the beginning of the stream
        stream.Position = 0;
        // Compute the hash of the stream and convert to a string
        hash = myHasher.ComputeHash(stream).ByteArrayToString();
    }
    // reset location
    stream.Position = position;         
    return hash;
}