C# 检查C中的标准输入#

C# 检查C中的标准输入#,c#,.net,console,stdin,C#,.net,Console,Stdin,我正在编写一个小型命令行实用程序,其目的是解析另一个实用程序的输出。我希望它可以通过两种方式调用: c:\> myutility filewithoutput.txt 或者 所以,基本上,标准的in或file参数。我的第一次尝试是这样的: TextReader reader; if (args.Length > 1) { reader = new StreamReader(new FileStream(args[1], FileMode.Open)); } else {

我正在编写一个小型命令行实用程序,其目的是解析另一个实用程序的输出。我希望它可以通过两种方式调用:

c:\> myutility filewithoutput.txt
或者

所以,基本上,标准的in或file参数。我的第一次尝试是这样的:

TextReader reader;

if (args.Length > 1) {
    reader = new StreamReader(new FileStream(args[1], FileMode.Open));
} else {
    reader = Console.In;
}

Process(reader);
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);
file参数工作正常,通过管道将输出从实用程序传输到my实用程序工作正常,但是如果您只是正常调用它(没有参数和管道数据),它将挂起。或者,更确切地说,它阻止了等待从中读取标准

我的第二稿是这样的:

TextReader reader;

if (args.Length > 1) {
    reader = new StreamReader(new FileStream(args[1], FileMode.Open));
} else {
    reader = Console.In;
}

Process(reader);
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);

虽然
KeyAvailable
修复了“无输入”问题,但如果您尝试通过管道导入数据,它会引发一个异常情况>\up>快速而肮脏的方法是在try/catch中包装Console.KeyAvailable,如果抛出,您知道输入是从文件重定向的。在找不到合适的方法来执行检查时,使用try/catch来检测状态并不罕见。

看起来您应该能够使用一些Windows API调用来确定该状态。甚至有一个助手类来总结这一切。

我已经使用Pieter的解决方案一段时间了,直到我意识到它在Mono中不起作用。Mono在使用管道输入检索Console.KeyAvailable时不会抛出异常,因此这种方法没有帮助

但是,从.NET 4.5开始,
Console
实际上提供了一个新字段
IsInputRedirected
,它使这一点更加简单,消除了模糊性和不必要的
try
/
捕获

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

这是否相关@bzlm-为什么不直接链接到源代码(这恰好是堆栈溢出):@John Oh,所以我输入的搜索词中so没有排名最高是我的错。:)@bzlm-肯定是SE的错,不是你的错!我会同意Pieter的答案,因为它可能更便于携带(不是说便携性是一个因素,但你永远不知道)。然而,好消息。。。。我真的很讨厌答案如此明显,它们从我身边飞过。尽管如此,我仍然不喜欢这样一个事实,即没有内置的方法来实现这一点……不幸的是,这在Mono中似乎不起作用。仅仅5年后再次回顾这一点,这听起来像是新的正确答案。酷!
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);
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);