【问题标题】:Fast Directory Listing using Shell ( DIR )使用 Shell ( DIR ) 的快速目录列表
【发布时间】:2017-09-18 10:56:43
【问题描述】:

我正在做一些工作以优化在 C#、文件和文件夹中跨网络驱动器列出文件夹的内容。对于文件,我需要 FileName、File Size 和 DateModified,对于文件夹,我只需要 Name 和 DateModified。

我在 StackOverflow 上搜索了各种解决方案并决定使用 Directory.GetFiles,使用 EnumerateFiles 没有任何好处,因为我没有并行处理文件。

我的测试用例在 WAN 上具有 4000 个和 5 个子文件夹,GetFiles 仍可能需要 30 秒或更长时间,但 Windows 可以在 2 秒内 DIR 文件夹。

我不想涉及太多的 Windows API 代码,所以我认为一个很好的中间立场是 Shell out the DIR 命令,重定向标准输出并解析输入。不漂亮,但应该没问题。我发现这段代码几乎可以满足我的需求:

Process process = new Process();
process.StartInfo.FileName = "ipconfig.exe";        
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;        
process.Start();

// Synchronously read the standard output of the spawned process. 
StreamReader reader = process.StandardOutput;
string output = reader.ReadToEnd();

这适用于 ipconfig.exe,但 DIR 不是 exe,所以我可以如何称呼它?我想重定向这样的东西:

目录“\MyNasDrive\MyFolder”

在最坏的情况下,我可以将它封装在一个 .bat 文件中,但这感觉相当可怕。

任何想法表示赞赏。

== 找到了我自己的解决方案,但如果您发现它有任何问题,请告诉我 ==

string DirPath = "\\\\MYServer\\MyShare\\";

Process process = new Process();
process.StartInfo.FileName = "C:\\Windows\\System32\\cmd.exe";
process.StartInfo.Arguments = "/C DIR /-C \"" + DirPath + "\"";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.CreateNoWindow = true;
process.Start();

// Synchronously read the standard output of the spawned process. Note we aren't reading the standard err, as reading both
// Syncronously can cause deadlocks. https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput(v=vs.110).aspx
//if we need to do this in the future then might be able to use https://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline(v=vs.110).aspx
StreamReader reader = process.StandardOutput;
string output = reader.ReadToEnd();

process.WaitForExit();
process.Close();

【问题讨论】:

  • there's no benefit in using EnumerateFiles 当您使用EnumerateFiles 而不是GetFiles 时,代码需要多长时间?
  • 代码使用 EnumerateFile 以相同的速度运行,因为在 EnumerateFile 调用之后,我需要一个循环来读取所有值。如果不读取所有值,我的代码将无法继续,因此我认为没有任何速度优势。显然,如果我正在加载文件,那么我可以将其并行化,但我只是在读取文件名、大小和 DateModified。

标签: c# directory createprocess processstartinfo


【解决方案1】:

DIR 不是 exe 文件

cmd.exe 是一个 exe。

使用 2 个参数调用 cmd.exe

  • /C
  • dir

注意:您也可以将 UseShellExecute 设置为 true。

【讨论】:

    猜你喜欢
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 2011-04-04
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    相关资源
    最近更新 更多