【发布时间】:2010-09-17 00:06:41
【问题描述】:
我知道如何使用参数对控制台应用程序进行编程,例如:myProgram.exe param1 param2。
我的问题是,如何使我的程序与 | 一起工作,例如:echo "word" |我的程序.exe?
【问题讨论】:
我知道如何使用参数对控制台应用程序进行编程,例如:myProgram.exe param1 param2。
我的问题是,如何使我的程序与 | 一起工作,例如:echo "word" |我的程序.exe?
【问题讨论】:
您需要像阅读用户输入一样使用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>【讨论】:
Console.ReadLine 的文档指出,如果没有更多要读取的行,它将返回 null:msdn.microsoft.com/de-de/library/…
Console.In 是对环绕标准输入流的 TextReader 的引用。当向您的程序输送大量数据时,使用这种方式可能会更容易。
【讨论】:
提供的示例有问题。
while ((s = Console.ReadLine()) != null)
如果程序在没有管道数据的情况下启动,将等待输入。所以用户必须手动按任意键退出程序。
【讨论】:
当数据或未通过管道传输时,以下内容不会暂停应用程序的输入和工作。有点小技巧;并且由于错误捕获,当进行大量管道调用时性能可能会有所下降,但是......很容易。
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
}
【讨论】:
System.Console.WriteLine(System.Console.IsInputRedirected.ToString());
这是从其他解决方案加上 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;
}
}
【讨论】:
System.Console.WriteLine(System.Console.IsInputRedirected.ToString());
这是这样做的方法:
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
【讨论】:
在 .NET 4.5 中是
if (Console.IsInputRedirected)
{
using(stream s = Console.OpenStandardInput())
{
...
【讨论】:
这也适用于
c:\MyApp.exe
我必须使用 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);
}
}
【讨论】: