Проверка стандартного ввода в C #

Я пишу небольшую утилиту командной строки, целью которой является анализ вывода другой утилиты. Я хочу, чтобы его можно было вызывать двумя способами:

c:\> myutility filewithoutput.txt

Или,

c:\> otherutility -args | myutility

Итак, в основном, стандартный аргумент in или file. Моя первая попытка выглядела так:

TextReader reader;

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

Process(reader);

Аргумент файла работает нормально, и передача вывода из утилиты в мою утилиту работает нормально, но если вы просто вызываете его в обычном режиме (без аргументов и без передаваемых данных), он зависает. Или, скорее, он блокируется при ожидании чтения из стандартного in.

Мой второй черновик выглядел так:

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 устраняет проблему «нет ввода», он генерирует исключение, если вы пытаетесь передать данные по конвейеру> _ <

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

Исключение предлагает использовать 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);

Однако здесь та же проблема, что и при первой попытке: он блокирует поиск ввода. Argh!

Что-то мне не хватает?

Примечание: я знаю соглашение об использовании аргумента «-», означающего «использовать стандартный ввод». Я воспользуюсь этим, если не будет другого пути. Но, конечно, должен быть какой-то способ определить, является ли консоль стандартным или нет!

Edit: Вот последняя версия, которая, кажется, делает то, что мне нужно:

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

Не большой поклонник использования исключений для потока, например это, но ... а.

14
задан Marc Mutz - mmutz 21 April 2011 в 15:21
поделиться