Sto scrivendo una piccola utility da riga di comando il cui scopo è analizzare l'output di un'altra utility. Io voglio che sia richiamabile in due modi:Controllo input standard in C#
c:\> myutility filewithoutput.txt
Oppure,
c:\> otherutility -args | myutility
Quindi, in sostanza, di serie o un file come argomento. Il mio primo tentativo di questo si presentava così:
TextReader reader;
if (args.Length > 1) {
reader = new StreamReader(new FileStream(args[1], FileMode.Open));
} else {
reader = Console.In;
}
Process(reader);
L'argomento file funziona bene, e piping l'uscita dal programma di utilità per il mio programma di utilità funziona bene, ma solo se si richiama normalmente (senza argomenti e con nessun dato convogliato) , si blocca. O, piuttosto, si blocca su in attesa di leggere da standard
Il mio secondo progetto si presentava così:.
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);
Mentre KeyAvailable
correzioni del "nessun input" problema, viene generata un'eccezione se si tenta di pipe nei dati> _ <
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
L'eccezione suggerisce che uso Console.In.Peek
, quindi il mio prossimo progetto è in quanto tale:
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);
Tuttavia, questo ha lo stesso problema del primo tentativo: blocca, cercando input. Argh!
C'è qualcosa che mi manca?
Sidenote: Sono a conoscenza della convenzione dell'argomento "-" che significa "utilizza input standard". Lo userò se non c'è altro modo. Ma, sicuramente, ci deve essere un modo per scoprire se lo standard è la console o no!
Edit: Ecco la versione finale che sembra fare quello che mi serve:
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);
Non è un grande fan di utilizzare eccezioni per il flusso del genere, ma ... eh.
È questo rilevante? http: // efreedom.it/Domanda/1-3453220/Rileva-ConsoleIn-Stdin-Redirected – bzlm
@bzlm - perché non collegarsi direttamente alla fonte (che capita di essere Stack Overflow): http://stackoverflow.com/questions/3453220 –
@John Oh , quindi è * mia * colpa che SO non abbia il punteggio più alto per i termini di ricerca inseriti. :) – bzlm