-->

在目录中搜索所有文件时显示进度(Show progress when searching all f

2019-07-31 12:45发布

我以前提出的问题得到快速的具体路径中的所有文件和目录 ,以便找到文件的最快越好。 我使用,以便解决方案找到匹配正则表达式的文件名。

我希望能显示一个进度条,因为有一些很庞大而缓慢的硬盘驱动器,它仍然需要大约1分钟来执行。 这种解决方案我张贴的其他链接不使我懂得更多的文件丢失,以遍历给我显示一个进度条。

一个解决方案,我想这样做是想获得我刨遍历目录的大小 。 例如,当我用鼠标右键单击该文件夹C:\Users ,我能得到的该目录是有多大的估计。 如果我能知道的大小,然后我就可以通过增加每一个,我觉得文件的大小,以显示进度。 换句话说,进度=(当前文件大小的总和)/目录大小

出于某种原因,我一直没能有效地得到该目录的大小。

一些对堆栈溢出的问题,用下面的办法:

但要注意,我得到一个异常而无法枚举文件。 我在想我的C盘上的方法古玩。

在那张照片我是想算,以显示进度的文件数量。 我很可能不会是能够得到有效地使用这种方法的文件数量 。 我在那里只是想一些关于堆栈溢出的答案,当有人问how to get the number of files on a directory ,也有人问how the get the size fa directory

Answer 1:

解决这个要离开你的几个可能性之一...

  1. 不显示进度
  2. 使用前期成本来计算(如Windows)
  3. 执行该操作计算成本

如果速度是重要的,你希望大目录树我会瘦到最后的这些选项。 我已经添加上链接的问题的答案获取特定的路径快速的所有文件和目录 ,演示文件计数和尺寸比目前使用的是更快的方式。 结合此成用于选项#3多线程的代码,以下可以进行...

static void Main()
{
    const string directory = @"C:\Program Files";
    // Create an enumeration of the files we will want to process that simply accumulates these values...
    long total = 0;
    var fcounter = new CSharpTest.Net.IO.FindFile(directory, "*", true, true, true);
    fcounter.RaiseOnAccessDenied = false;
    fcounter.FileFound +=
        (o, e) =>
            {
                if (!e.IsDirectory)
                {
                    Interlocked.Increment(ref total);
                }
            };

    // Start a high-priority thread to perform the accumulation
    Thread t = new Thread(fcounter.Find)
        {
            IsBackground = true, 
            Priority = ThreadPriority.AboveNormal, 
            Name = "file enum"
        };
    t.Start();

    // Allow the accumulator thread to get a head-start on us
    do { Thread.Sleep(100); }
    while (total < 100 && t.IsAlive);

    // Now we can process the files normally and update a percentage
    long count = 0, percentage = 0;
    var task = new CSharpTest.Net.IO.FindFile(directory, "*", true, true, true);
    task.RaiseOnAccessDenied = false;
    task.FileFound +=
        (o, e) =>
            {
                if (!e.IsDirectory)
                {
                    ProcessFile(e.FullPath);
                    // Update the percentage complete...
                    long progress = ++count * 100 / Interlocked.Read(ref total);
                    if (progress > percentage && progress <= 100)
                    {
                        percentage = progress;
                        Console.WriteLine("{0}% complete.", percentage);
                    }
                }
            };

    task.Find();
}

该的FindFile类的实现,可以发现FindFile.cs 。

根据您的文件处理任务有多贵(该ProcessFile以上功能),你应该看到对大容量文件的进度非常干净的进展。 如果你的文件处理速度非常快,你可能需要增加枚举的开始之间的滞后和处理的开始。

事件参数的类型的FindFile.FileFoundEventArgs并是一个可变类,所以可以肯定你不保持到事件参数,因为它的价值会发生变化的参考。

理想情况下,你将要添加的错误处理,并可能中止双方枚举的能力。 中止枚举可以通过设置“CancelEnumeration”对事件的说法来完成。



Answer 2:

由于文件系统存储它是如何的数据你问是不可能的。

这是一个文件系统的限制

没有办法知道一个文件夹的总大小 ,也不是总文件数的文件夹里面没有列举的文件一个接一个 。 无论这些信息都存储在文件系统中。

这就是为什么视窗显示这样的消息"Calculating space"有很多文件的复制文件夹之前...它实际上是计数多少文件有文件夹内,它们的大小相加,以便它可以显示进度条,而这样做真正的复制操作。 (也有用的信息知道目的地有足够的空间来容纳复制所有数据)。

此外,当你右击一个文件夹,选择属性,注意,它需要一些时间来算的所有文件,并总结了所有文件的大小。 这是由相同的限制引起的。

要知道一个文件夹有多大,或者多少文件有一个文件夹里面,你必须一个接一个枚举文件。

快速文件枚举

当然,你已经知道,有很多做枚举本身的方式......但没有人会瞬间。 你可以尝试使用USN日志文件系统做的扫描。 看看这个项目的CodePlex: 在VB.NET MFT扫描仪 ( 代码实际上是在C#...不知道为什么笔者说,这是VB.NET)...它找到了所有文件在我的IDE SATA(未SSD)驱动器在不到15秒,发现311000页的文件。

你将不得不通过路径,文件过滤,因此只有您正在寻找的路径中的文件被返回。 但是,这是工作的最简单的部分!

希望这有助于在你的项目...祝你好运!



文章来源: Show progress when searching all files in a directory