C#将处理结果重定向到文本文件

时间:2015-04-16 19:58:14

标签: c# append command-line-arguments

我一直绞尽脑汁想弄清楚为什么我不能使用>> (追加)作为我的p.StartInfo.Argument的一部分。当我删除">"它工作得很完美,但我尝试使用">"或">>"我得到一个"不正确的参数"错误。我已经开始编写我的程序而没有>或>>然后将输出存储到字符串中,稍后将其写入文件。有人可以解释为什么">"或">>"在这种情况下不会起作用吗?

// Start the child process.
 Process p = new Process();
 // Redirect the output stream of the child process.
 p.StartInfo.UseShellExecute = false;
 p.StartInfo.RedirectStandardOutput = true;
 p.StartInfo.FileName = "attrib.exe";
startInfo.Arguments = "/S *.jpg > mypics.txt";

 p.Start();

3 个答案:

答案 0 :(得分:0)

这是因为>>>不是由attrib.exe解释的参数,而是cmd.exe的指示。

您可以尝试使用以下内容:

p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c attrib.exe /S *.jpg > mypics.txt";

另外,这是一只红鲱鱼:

p.StartInfo.RedirectStandardOutput = true;

如果您想阅读C#代码中的输出并自行编写文件,则可以使用此选项。它对使用>输出重定向器没有帮助。

答案 1 :(得分:0)

输出重定向运算符>cmd.exe的一个功能,而不是操作系统。因此,使用它的天真方式就是调用cmd

p.StartInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C \"attrib.exe /S *.jpg > mypics.txt\"";

然而,重定向输出的正确方法是首先将StartInfo.RedirectStandardOutput设置为true(您所做的),然后将Process.StandardOutput的输出传输到文件,如这样:

using(StreamWriter file = new StreamWriter("mypics.txt")) {
    p.StandardOutput.CopyTo(file);
}

或者,异步版本:

using(StreamWriter file = new StreamWriter("mypics.txt")) {
    await p.StandardOutput.CopyToAsync(file);
}

答案 2 :(得分:0)

SlugFiller的解决方案很好,但不能可靠地与大量输出配合使用。问题在于,如果进程输出的文本过多,则由于流达到最大缓冲区大小而挂起。换句话说,在流程运行时需要将流后台处理,以防止缓冲区填满。

但是,有一种方法可以使用任务从输出流中接收数据并实时后台处理。

// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "attrib.exe";
startInfo.Arguments = "/S *.jpg > mypics.txt";
p.Start();


Thread stdoutThread = new Thread(new ThreadStart(WriteStandardOutput));
stdoutThread.IsBackground = true;
stdoutThread.Name = "stdout_writer";
stdoutThread.Start();

private void WriteStandardOutput()
{
    using (StreamWriter sw = File.CreateText(ConsoleLogFileFullPath))
    using (StreamReader sr = p.StandardOutput)
    {
        for (;;)
        {
            string line = sr.ReadLine();
            if (line == null)
                break;
            sw.WriteLine(textLine);
        }
        sw.Flush();
    }
}

在某些时候,请确保调用stdoutThread.Join()以确保线程完成。我已经用一些生成大量输出的代码进行了测试,仍然有可能溢出缓冲区,或者用极长的行中断ReadLine(),但是它确实可以在几千个数量级的情况下非常快速地输出每秒80个字符行。