【问题标题】:C# MD5 hash taking up no disk IO but is producing a hashC# MD5 哈希不占用磁盘 IO,但正在生成哈希
【发布时间】:2014-07-07 20:30:00
【问题描述】:

我觉得这很奇怪。我有一个我正在使用的实用程序,它将指向一个文件夹,用相对路径/文件名/文件大小/md5哈希/其他一些东西索引文件夹。如果 md5 散列不匹配,它会更新数据库中的散列,再次备份文件,然后继续处理其余文件。这主要是出于备份目的,但也是我的倾向。

我第一次针对我的一些 Web 项目运行该程序时,它使用了磁盘 IO 和抓取文件句柄,这两者都在 Process Hacker 中可见。但是,第二次运行它(例如,我关闭它并重新启动它),它似乎没有占用任何磁盘 IO,只是定期抓取一个句柄。然而,一个哈希出现了。

遍历文件的代码:

        foreach (string path in paths)
        {
            try
            {
                string relativePath = path.Replace(@"Z:\99_Projects\web\de.com\", "");
                BackupFile backupFile = BackupFile.GetFile(relativePath, connection);
                string md5hash = "";
                long filesize = (new FileInfo(path)).Length;

                using (var file = File.OpenRead(path))
                {
                    md5hash = Hasher.ComputeMD5Hash(file);
                    //Console.WriteLine(md5hash);
                    if (backupFile == null)
                    {
                        BackupFile.NewBackupFile(relativePath, Path.GetFileName(path), md5hash, filesize, connection);
                    }
                    else
                    {
                        if (backupFile.md5 != md5hash)
                            backupFile.flags = CoreLib.Utils.Backup.Enums.BackupFileFlags.CHANGED;
                        else
                            backupFile.flags = CoreLib.Utils.Backup.Enums.BackupFileFlags.UNCHANGED;

                        backupFile.filesize = filesize;
                        backupFile.md5 = md5hash;
                        backupFile.Save(connection);
                    }

                    file.Close();
                }
            }
            catch (IOException e)
            {
                Console.WriteLine("Access: " + Path.GetFileName(path));
            }
            catch (SQLiteException e)
            {
                Console.WriteLine("|E|");
            }
            catch (Exception e)
            {
                Console.WriteLine("|EG|");
                throw e;
            }
        }

所使用的 Hasher 类的代码,它实际上只是密码学 MD5 哈希计算器的一个小方法包装器,因此我可以在其他代码的其他地方重用它(以及我粘贴在其中的其他哈希方法)。

public class Hasher
{
    public static string ComputeMD5Hash(Stream stream)
    {
        string hash = "";
        using (var md5 = System.Security.Cryptography.MD5.Create())
        {
            hash = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();                   
        }
        return hash;
    }
}

我尝试了几件事,包括调试应用程序并验证它实际上是在打开文件流并计算哈希值。我还让它将哈希打印到控制台,如计算位置下的注释行所示,但即使它打印出来,它也根本没有显示磁盘 IO。

【问题讨论】:

  • 文件很可能被缓存在内存中,因此没有实际的磁盘 I/O。至于没有得到句柄,我想它可能是得到了句柄并很快释放它,以至于你的监视器没有时间报告它。
  • 确定不只是操作系统文件系统缓存在起作用?
  • @ChrisJ 是这么想的,但我不确定在哪里可以禁用它,或者至少找出它是否正在这样做。我可以在哪里调查?此外,由于文件系统缓存,它可能会如此快速地抓取它们。它确实显示了一个,但非常简短,所以这是有道理的。
  • 好吧,我想测试是否是操作系统缓存的一种方法是尝试完全重新启动,并且像你一样,观察文件 I/O。
  • "我实际上更改了其中一个文件。"并且文件系统在您保存文件时缓存了该文件。并且实际的磁盘 I/O 可能发生在更晚的时间——当操作系统开始将其缓存刷新到磁盘时。

标签: c# hash


【解决方案1】:

好吧,它看起来好像是简单的文件系统缓存,而 Process Hacker 的轮询速度太慢,一旦缓存就无法获取。我更改了一个文件,它检测到了更改,但根本没有显示可测量的磁盘 IO(它以字节为单位),所以我假设此时它只是由于运行速度太快而没有接收到它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    • 2014-05-19
    • 2020-12-08
    • 2012-08-17
    • 2017-05-24
    • 1970-01-01
    相关资源
    最近更新 更多