Я пишу небольшую утилиту командной строки, целью которой является анализ выходных данных другой утилиты. Я хочу, чтобы это было вызвано двумя способами:
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);
Аргумент file работает нормально, и передача вывода из утилиты в мою утилиту работает нормально, но если вы просто вызываете его нормально (без аргументов и без данных), он зависает. Или, скорее, он блокирует ожидание чтения из стандартного входа.
Мой второй черновик выглядел так:
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
исправляет проблему «без ввода», оно выдает исключение, если вы пытаетесь передать данные> _ <</p>
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!
Я что-то упускаю?
Sidenote: Мне известно о соглашении аргумента "-", означающего "использовать стандартный ввод". Я буду использовать это, если нет другого пути. Но, безусловно, должен быть какой-то способ определения, является ли стандартная консоль или нет!
Редактировать: вот последняя версия, которая, кажется, делает то, что мне нужно:
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);
Не большой поклонник использования исключений для таких потоков, но ... эх.