。净。以编程方式检查目录是否已更改或对目录

时间:2016-08-25 16:50:49

标签: c# directory

有人能告诉我一种有效的方法来检查目录及其内容是否已使用C#进行了更改?程序没有一直运行,因此FileWatcher不是一个选项。此外,这项测试必须快速完成,不必完美,只是非常好。通过这个我的意思是,如果我能够快速检查给定目录,相同的子目录仍然存在,我会很高兴。并且文件名相同,文件大小相同。我想验证“修改日期”可能也不错。打开每个文件并验证内容是不必要或不可取的。这将花费太长时间。我可以轻松地将信息(文件大小等)保存到文件中,并在下次运行程序时读取它。

这样做的背景是我正在开发一个搜索程序来搜索我们的专有文件。我将结果保存到JSON文件,下次搜索完成后,我只需从JSON中读取。当然,只有目录(或子目录)没有改变。

我发布了以下用于检查的代码。这太慢了。最大的时间是检查所有目录是否匹配,但即使是第一行(“Directory.Exists”)也需要一些时间。

如果我能提供更多细节或澄清,请告诉我。

谢谢,

戴夫

            if (Directory.Exists(directoryCache.DirectoryName) == false)
            return false;

        // look at sessZip
        ulong fileSize = 0;
        string[] sessZipEntries = Directory.GetFiles(directoryCache.DirectoryName,
    "*.sessZip", SearchOption.TopDirectoryOnly);
        foreach (string fileName in sessZipEntries)
        {
            FileInfo fileInfo = new FileInfo(fileName);
            fileSize += (ulong)fileInfo.Length;
        }

        if (fileSize != directoryCache.SessZipSize)
            return false;


        string[] directories = Directory.GetDirectories(directoryCache.DirectoryName);
        foreach (string directory in directories)
        {
            if (directoryCache.SubDirectoriesList.FirstOrDefault(x => x.DirectoryName == directory) == null)
            {
                return false;
            }
        }
        foreach (DirectoryCacheItem subDir in directoryCache.SubDirectoriesList)
        {
            if (directories.Contains(subDir.DirectoryName) == false)
            {
                return false;
            }
        }

        return true;

2 个答案:

答案 0 :(得分:1)

您可能需要散列文件夹的内容并将其存储起来。然后就比较吧。 MD5应该足够了。

如果您想要更轻松,可以按照MS示例进行操作,但这并非万无一失。 https://msdn.microsoft.com/en-us/library/mt693036.aspx

答案 1 :(得分:0)

根据Tim的回答(我将其标记为答案),我能够找到一个非常好的,快速的解决方案来检查目录是否没有改变。感谢蒂姆的想法和链接。我有:

public bool VerifyCacheIntegrity()
    {
        if (_directoryCache == null || string.IsNullOrEmpty(_directoryCache.DirectoryName))
            return false;

        System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(_directoryCache.DirectoryName);
        FileInfo[] list1 = dir1.GetFiles("*.sessZip", System.IO.SearchOption.AllDirectories);

        FileCompare myFileCompare = new FileCompare();


        return list1.SequenceEqual(_directoryCache.FileInfoLst, myFileCompare); 

    }

FileCompare定义为:

internal class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
{
    public FileCompare() { }

    public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
    {
        return (f1.Name == f2.Name &&
                f1.Length == f2.Length);
    }

    // Return a hash that reflects the comparison criteria. According to the 
    // rules for IEqualityComparer<T>, if Equals is true, then the hash codes must
    // also be equal. Because equality as defined here is a simple value equality, not
    // reference identity, it is possible that two or more objects will produce the same
    // hash code.
    public int GetHashCode(System.IO.FileInfo fi)
    {
        string s = String.Format("{0}{1}", fi.Name, fi.Length);
        return s.GetHashCode();
    }
}

显然,FileCompare可以扩展到包括&#34;修改日期&#34;比较或其他任何东西。最后,为了完整起见,我展示了如何填充FileInfoLst。这是最终进入文件的列表,并提供目录结构的快照。

public bool BuildTree(string directory, string searchItem = null, List<string> matches = null, string searchField = null)
    {
        if (!Directory.Exists(directory))
            return false;

        _directoryCache = BuildDirectoryCache(directory, searchItem, matches, searchField);

        System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(directory);

        FileInfo[] list1 = dir1.GetFiles("*.sessZip", System.IO.SearchOption.AllDirectories);
        _directoryCache.FileInfoLst = list1;
        return true;
    }