C# 控制台通过管道接收输入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/199528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:42:46  来源:igfitidea点击:

C# Console receive input with pipe

c#pipe

提问by Patrick Desjardins

I know how to program Console application with parameters, example : myProgram.exe param1 param2.

我知道如何使用参数对控制台应用程序进行编程,例如:myProgram.exe param1 param2。

My question is, how can I make my program works with |, example : echo "word" | myProgram.exe?

我的问题是,如何让我的程序与 | 一起工作,例如:echo "word" | 我的程序.exe?

采纳答案by Matthew Scharley

You need to use Console.Read()and Console.ReadLine()as if you were reading user input. Pipes replace user input transparently. You can't use both easily (although I'm sure it's quite possible...).

您需要使用Console.Read()andConsole.ReadLine()就好像您正在阅读用户输入一样。管道透明地替换用户输入。您不能轻松地同时使用两者(尽管我确定这很有可能......)。

Edit:

编辑:

A simple catstyle program:

一个简单的cat样式程序:

class Program
{
    static void Main(string[] args)
    {
        string s;
        while ((s = Console.ReadLine()) != null)
        {
            Console.WriteLine(s);
        }

    }
}

And when run, as expected, the output:

运行时,如预期的那样,输出:

C:\...\ConsoleApplication1\bin\Debug>echo "Foo bar baz" | ConsoleApplication1.exe
"Foo bar baz"

C:\...\ConsoleApplication1\bin\Debug>

回答by Joel Mueller

Console.In is a reference to a TextReader wrapped around the standard input stream. When piping large amounts of data to your program, it might be easier to work with that way.

Console.In 是对环绕标准输入流的 TextReader 的引用。当将大量数据通过管道传输到您的程序时,使用这种方式可能更容易。

回答by Alex N

there is a problem with supplied example.

提供的示例存在问题。

  while ((s = Console.ReadLine()) != null)
  while ((s = Console.ReadLine()) != null)

will stuck waiting for input if program was launched without piped data. so user has to manually press any key to exit program.

如果程序在没有管道数据的情况下启动,将卡在等待输入。所以用户必须手动按任意键退出程序。

回答by CodeMiller

The following will not suspend the application for input and works when data is oris not piped. A bit of a hack; and due to the error catching, performance could lack when numerous piped calls are made but... easy.

以下内容不会暂停输入的应用程序,并且在数据通过或未通过管道传输时起作用。有点黑客;并且由于错误捕获,当进行大量管道调用时,性能可能会下降,但......很容易。

public static void Main(String[] args)
{

    String pipedText = "";
    bool isKeyAvailable;

    try
    {
        isKeyAvailable = System.Console.KeyAvailable;
    }
    catch (InvalidOperationException expected)
    {
        pipedText = System.Console.In.ReadToEnd();
    }

    //do something with pipedText or the args
}

回答by Matthew Benedict

Here is another alternate solution that was put together from the other solutions plus a peek().

这是从其他解决方案加上 peek() 组合在一起的另一个替代解决方案。

Without the Peek() I was experiencing that the app would not return without ctrl-c at the end when doing "type t.txt | prog.exe" where t.txt is a multi-line file. But just "prog.exe" or "echo hi | prog.exe" worked fine.

如果没有 Peek(),我遇到了在执行“type t.txt | prog.exe”(其中 t.txt 是多行文件)时,如果没有 ctrl-c,应用程序将不会返回。但只是“prog.exe”或“echo hi | prog.exe”工作正常。

this code is meant to only process piped input.

此代码仅用于处理管道输入。

static int Main(string[] args)
{
    // if nothing is being piped in, then exit
    if (!IsPipedInput())
        return 0;

    while (Console.In.Peek() != -1)
    {
        string input = Console.In.ReadLine();
        Console.WriteLine(input);
    }

    return 0;
}

private static bool IsPipedInput()
{
    try
    {
        bool isKey = Console.KeyAvailable;
        return false;
    }
    catch
    {
        return true;
    }
}

回答by matt burns

This is the way to do it:

这是这样做的方法:

static void Main(string[] args)
{
    Console.SetIn(new StreamReader(Console.OpenStandardInput(8192))); // This will allow input >256 chars
    while (Console.In.Peek() != -1)
    {
        string input = Console.In.ReadLine();
        Console.WriteLine("Data read was " + input);
    }
}

This allows two usage methods. Read from standard input:

这允许两种使用方法。从标准输入读取:

C:\test>myProgram.exe
hello
Data read was hello

or read from piped input:

或从管道输入读取:

C:\test>echo hello | myProgram.exe
Data read was hello

回答by gordy

in .NET 4.5 it's

在 .NET 4.5 中

if (Console.IsInputRedirected)
{
    using(stream s = Console.OpenStandardInput())
    {
        ...

回答by Si Zi

This will also work for

这也适用于

c:\MyApp.exe < input.txt

c:\MyApp.exe < input.txt

I had to use a StringBuilder to manipulate the inputs captured from Stdin:

我不得不使用 StringBuilder 来操作从 Stdin 捕获的输入:

public static void Main()
{
    List<string> salesLines = new List<string>();
    Console.InputEncoding = Encoding.UTF8;
    using (StreamReader reader = new StreamReader(Console.OpenStandardInput(), Console.InputEncoding))
    {
        string stdin;
        do
        {
            StringBuilder stdinBuilder = new StringBuilder();
            stdin = reader.ReadLine();
            stdinBuilder.Append(stdin);
            var lineIn = stdin;
            if (stdinBuilder.ToString().Trim() != "")
            {
                salesLines.Add(stdinBuilder.ToString().Trim());
            }

        } while (stdin != null);

    }
}