【发布时间】: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