只访问目录,获取目录下所有文件的属性

3
我正在尝试编写一个C#函数,该函数将目录路径作为参数并返回一个字典,其中键是该目录下直接的文件,值是它们的最后修改时间。使用Directory.GetFiles()然后File.GetLastWriteTime()很容易实现。但是,这意味着必须访问每个文件,这对我的需求来说太慢了。有没有一种方法可以在仅访问目录的情况下完成此操作?文件系统是否支持这种要求?
编辑后,阅读了一些答案: 谢谢你们,你们都说得非常相似 - 使用FileInfo对象。但是,使用Directory.GetFiles()(或Directory.EnumerateFiles())获取这些对象同样很慢,我怀疑获取它们需要访问每个文件。如果文件系统仅在文件本身中保留其文件的最后修改时间,则无法提取该信息而不进行文件访问。在这里是这种情况吗? DirectoryInfo的GetFiles()和EnumerateFiles()会访问每个文件还是从目录条目中获取文件信息?我知道,如果我只想获取文件名,我可以使用Directory类而不必访问每个文件。但是获取属性似乎更加棘手...
根据henk的回复,似乎使用FileInfo Object确实更快。我创建了以下测试:
static void Main(string[] args)
    {
        Console.WriteLine(DateTime.Now);

        foreach (string file in Directory.GetFiles(@"\\169.254.78.161\dir"))
        {
            DateTime x = File.GetLastWriteTime(file);
        }

        Console.WriteLine(DateTime.Now);

        DirectoryInfo dirInfo2 = new DirectoryInfo(@"\\169.254.78.161\dir");
        var files2 = from f in dirInfo2.EnumerateFiles()
                select f;
        foreach (FileInfo file in files2)
        {
            DateTime x = file.LastWriteTime;
        }

        Console.WriteLine(DateTime.Now);
    }

对于大约800个文件,我通常会得到类似以下的结果:
2011年8月31日17:14:48
2011年8月31日17:14:51
2011年8月31日17:14:52


2
不需要访问文件,只需访问MFT中的目录条目即可获取此信息。如果速度太慢,您需要更快的磁盘。 - Hans Passant
@Yoni:你是如何/用什么方式进行测量的?你是否将调用GetFiles与打开/关闭每个文件的循环进行了比较?我预计GetFiles()在处理100|200个文件时需要大约相同的时间,而循环则需要两倍的时间。 - H H
我认为你是正确的。我进行了一些测试,请参见上面的编辑。 - Yoni
很抱歉告诉你,但是你的测试存在严重缺陷。由于缓存的原因,第二次运行总是更快。无论如何,消除缓存非常困难,而且网络也会影响测试结果。在本地磁盘上进行测试,交替运行,并使用“System.Diagnostics.Stopwatch”类。 - H H
有趣的是,我使用了网络驱动器,因为我认为本地驱动器上的缓存更重(也因为我打算让此功能在网络驱动器上工作)。我确实复制了测试目录,试图消除缓存因素,并且我改变了顺序。结果相似。 - Yoni
2个回答

2

我没有做任何计时,但你最好的选择是:

DirectoryInfo di = new DirectoryInfo(myPath);
FileInfo[] files = di.GetFiles();

我认为所有的FileInfo属性都可以在目录文件记录中获得,因此这可能需要最少的I/O。


我不知道GetFiles()是如何实现的,但根据我测量的时间,它似乎访问每个文件以获取信息。 - Yoni

1

我能想到的另一件事就是使用FileInfo类。据我所知,这可能会对您有所帮助,或者也可能读取文件(需要读取权限)。


谢谢。我不确定你的意思,但这个链接可能会有所帮助:http://msdn.microsoft.com/en-us/library/dd413232.aspx - Yoni
那只是一种获取FileInfo对象的方式,就像我说的那样。我不知道这些*Info对象在内部是否与您的原始代码行为相同...但无论如何都没关系。 - Random Dev
在 DirectoryInfo 对象上应用 EnumerateFiles() 将返回所有 FileInfo 对象,其中包括我需要的最后写入时间。然而,它仍会访问每个文件。 - Yoni
这正是我想用“或者它也可以读取文件”的方式来表达的 - 我想没有更好的方法了。也许一些WinAPI巫师在Windows深处隐藏着一些魔法,但对于框架,我想不出其他解决方案。 - Random Dev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接