【问题标题】:Get attributes of all files under a directory while accessing the directory only仅访问目录时获取目录下所有文件的属性
【发布时间】:2011-11-07 13:12:23
【问题描述】:

我正在尝试在 C# 中编写一个函数,该函数获取目录路径作为参数并返回一个字典,其中键是该目录下的文件,值是它们的最后修改时间。 使用 Directory.GetFiles() 和 File.GetLastWriteTime() 很容易做到这一点。但是,这意味着必须访问每个文件,这对于我的需要来说太慢了。 仅访问目录时有没有办法做到这一点?文件系统甚至支持这种要求吗?

编辑,在阅读了一些答案后: 谢谢你们,你们都说得差不多——使用 FileInfo 对象。尽管如此,使用 Directory.GetFiles()(或 Directory.EnumerateFiles())来获取这些对象同样慢,而且我怀疑获取它们需要访问每个文件。如果文件系统仅在文件本身中保留其文件的最后修改时间,则无法在没有文件访问权限的情况下提取该信息。这是这里的情况吗? DirectoryInfo 的 GetFiles() 和 EnumerateFiles() 是否访问每个文件或从目录条目中获取它们的信息?我知道,如果我只想获取文件名,我可以使用 Directory 类执行此操作,而无需访问每个文件。但是获取属性似乎更棘手......

根据亨克的回应进行编辑: 似乎使用 FileInfo 对象确实更快。我创建了以下测试:

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

【问题讨论】:

  • 不,此信息不需要访问文件,只需要访问 MFT 中的目录条目。如果速度太慢,您将需要更快的磁盘。
  • @Yoni:你如何/测量什么?您是否将对 GetFiles 的调用与打开/关闭每个文件的循环进行比较?我希望 GetFiles() 对 100|200 个文件花费大约相同的时间,而循环将花费两倍的时间。
  • 我认为你是对的。我做了一些测试,见上面的编辑
  • 很抱歉,您的测试存在严重缺陷。由于缓存,第二次运行总是会更快。无论如何,缓存都很难消除,而且它在网络上的事实也起到了一定的作用。在本地磁盘上进行测试,交替运行并使用 System.Diagnostics.Stopwatch 类。
  • 有趣的是,我使用网络驱动器是因为我认为本地驱动器上的缓存要重得多(也因为我打算将此功能用于网络驱动器)。我确实复制了测试目录,试图消除缓存因素,并且我确实改变了顺序。结果相似。

标签: c# .net file directory file-attributes


【解决方案1】:

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

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

我认为所有 FileInfo 属性在目录文件记录中都可用,因此这应该(可能)需要最少的 I/O。

【讨论】:

  • 我不知道GetFiles()是怎么实现的,但是根据我测的时间,好像它访问每个文件来获取信息
【解决方案2】:

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

【讨论】:

  • 谢谢。我不明白你的意思,但那有点帮助:msdn.microsoft.com/en-us/library/dd413232.aspx
  • 正如我所说,这只是获取 FileInfo-Objects 的一种方式。我不知道这些 *Info-Objects 的行为是否与您的原始代码内部相同......但没关系。
  • 在 DirectoryInfo 对象上应用 EnumerateFiles() 将返回所有 FileInfo 对象,包括我需要的最后写入时间。但是,它仍然会访问每个文件
  • 这正是我想说的“或者它也可能读取文件” - 我想没有更好的方法。也许一些 WinAPI 向导在 Windows 的内部深处隐藏了一些魔法,但对于框架我想不出另一种解决方案
猜你喜欢
  • 2013-12-31
  • 2014-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
  • 2023-03-31
相关资源
最近更新 更多