C#Console通过管道接收输入

时间:2008-10-14 00:14:07

标签: c# pipe

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

我的问题是,如何使我的程序与|,例如:echo“word”| myProgram.exe?

8 个答案:

答案 0 :(得分:43)

您需要使用Console.Read()Console.ReadLine(),就像您正在阅读用户输入一样。管道透明地替换用户输入。你不能轻易使用它们(虽然我确信它很可能......)。

修改

一个简单的cat样式程序:

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

    }
}

当按预期运行时,输出:

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

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

答案 1 :(得分:15)

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

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
}

答案 2 :(得分:11)

在.NET 4.5中

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

答案 3 :(得分:8)

这是做到这一点的方法:

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);
    }
}

这允许两种使用方法。阅读标准输入

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

或从管道输入

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

答案 4 :(得分:3)

这是另一个替代解决方案,它是从其他解决方案加上一个peek()。

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

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

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;
    }
}

答案 5 :(得分:2)

Console.In是对包含标准输入流的TextReader的引用。将大量数据传递给程序时,使用这种方式可能更容易。

答案 6 :(得分:1)

提供的示例存在问题。

  while ((s = Console.ReadLine()) != null)
如果在没有管道数据的情况下启动程序,

将等待输入。所以用户必须手动按任意键退出程序。

答案 7 :(得分:0)

这也适用于

  

c:\ MyApp.exe< input.txt中

我不得不使用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);

    }
}