Mik*_*ron 14 .net c# console stdin
我正在编写一个小命令行实用程序,其目的是解析另一个实用程序的输出.我希望它可以通过两种方式调用:
c:\> myutility filewithoutput.txt
Run Code Online (Sandbox Code Playgroud)
要么,
c:\> otherutility -args | myutility
Run Code Online (Sandbox Code Playgroud)
所以,基本上,标准或文件参数.我对此的第一次尝试看起来像这样:
TextReader reader;
if (args.Length > 1) {
reader = new StreamReader(new FileStream(args[1], FileMode.Open));
} else {
reader = Console.In;
}
Process(reader);
Run Code Online (Sandbox Code Playgroud)
文件参数工作正常,并将实用程序的输出传递给我的实用程序工作正常,但如果您只是正常调用它(没有参数和没有管道数据),它会挂起.或者说,它阻止等待从标准读取.
我的第二稿看起来像这样:
TextReader reader;
if (args.Length > 1) {
reader = new StreamReader(new FileStream(args[1], FileMode.Open));
} else {
if(Console.KeyAvailable) {
reader = Console.In;
} else {
Console.WriteLine("Error, need data");
return;
}
}
Process(reader);
Run Code Online (Sandbox Code Playgroud)
虽然KeyAvailable修复了"无输入"问题,但如果您尝试管道数据> _ <,则会引发异常
Unhandled Exception: System.InvalidOperationException: Cannot see if a key
has been pressed when either application does not have a console or when
console input has been redirected from a file. Try Console.In.Peek.
at System.Console.get_KeyAvailable()
at MyUtility.Program.Main(String[] args) in Program.cs:line 39
Run Code Online (Sandbox Code Playgroud)
我建议使用例外Console.In.Peek,所以我的下一个草案是这样的:
TextReader reader;
if (args.Length > 1) {
reader = new StreamReader(new FileStream(args[1], FileMode.Open));
} else {
if(Console.In.Peek() != 0) {
reader = Console.In;
} else {
Console.WriteLine("Error, need data");
return;
}
}
Process(reader);
Run Code Online (Sandbox Code Playgroud)
但是,这与第一次尝试有同样的问题:它阻塞,寻找输入.哎呀!
有什么我想念的吗?
旁注:我知道参数" - "的约定意味着"使用标准输入".如果没有别的办法,我会用它.但是,肯定有一些方法可以检测标准输入是否是控制台!
编辑:这是最终版本似乎做我需要的:
TextReader reader;
if (args.Length > 1) {
reader = new StreamReader(new FileStream(args[1], FileMode.Open));
} else {
try {
bool tmp = Console.KeyAvailable;
Console.WriteLine("Error, need data");
return;
} catch(InvalidOperationException) {
reader = Console.In;
}
}
Process(reader);
Run Code Online (Sandbox Code Playgroud)
不像那样使用Exceptions for flow,但是......呃.
Pie*_*kel 10
快速而肮脏的方法是将Console.KeyAvailable包装在try/catch中,如果抛出,则表示输入是从文件重定向的.当您找不到合适的方法来检查状态时,使用try/catch检测状态并不是很常见.
我一直在使用Pieter的解决方案,直到我意识到它在Mono中不起作用.Console.KeyAvailable使用管道输入检索Mono时不会抛出异常,因此该方法无效.
但是,从.NET 4.5开始,Console实际上提供了一个新的字段IsInputRedirected,使这更简单,删除了默默无闻和不必要的try/ catch:
TextReader reader;
if (args.Length > 1) {
reader = new StreamReader(new FileStream(args[1], FileMode.Open));
} else {
if (Console.IsInputRedirected) {
reader = Console.In;
} else {
Console.WriteLine("Error, need data");
return;
}
}
Process(reader);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7014 次 |
| 最近记录: |