2008-10-14 12 views

Antwort

37

Sie müssen Console.Read() und Console.ReadLine() verwenden, als würden Sie Benutzereingaben lesen. Pipes ersetzen die Benutzereingabe transparent. Sie können nicht beide einfach verwenden (obwohl ich bin mir sicher, dass es durchaus möglich ist ...).

Edit:

Ein einfaches cat Stil Programm:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string s; 
     while ((s = Console.ReadLine()) != null) 
     { 
      Console.WriteLine(s); 
     } 

    } 
} 

Und wenn laufen, wie erwartet, die Ausgabe:

 
C:\...\ConsoleApplication1\bin\Debug>echo "Foo bar baz" | ConsoleApplication1.exe 
"Foo bar baz" 

C:\...\ConsoleApplication1\bin\Debug> 
+1

Hat Ihr Beispiel funktioniert für: echo "Foo bar baz" | ConsoleApplication1.exe | Konsolenanwendung1.exe? –

+2

Ja. Mit einer niedrigeren Analogie, was wirklich mit einer Pipe passiert, ist der Stout-Stream der ersten Anwendung wird in den Stdin-Stream der nächsten Anwendung in der Pipeline gesteckt. Die stdin der Konsole wird durch die erste Anwendung geleitet und die letzte Anwendung wird angezeigt. –

+0

Morgen werde ich das versuchen !!! Thx :) –

2

Console.In ist ein Verweis auf eine TextReader um den Standard-Eingabestream gewickelt. Wenn Sie große Datenmengen zu Ihrem Programm leiten, ist es möglicherweise einfacher, auf diese Weise zu arbeiten.

1

Es gibt ein Problem mit dem mitgelieferten Beispiel.

while ((s = Console.ReadLine()) != null) 

wird warten Eingang stecken, wenn Programm ohne verrohrt Daten ins Leben gerufen wurde. Der Benutzer muss also manuell eine beliebige Taste drücken, um das Programm zu beenden.

+0

das ist mehr wert als ein Kommentar, und andere haben das angesprochen und eine Lösung dafür – barlop

13

Im Folgenden wird die Anwendung für die Eingabe nicht suspendieren und arbeitet, wenn Daten oder nicht verrohrt. Ein bisschen wie ein Hack; und wegen des Fehlers, der abfängt, könnte Leistung fehlen, wenn zahlreiche piped Anrufe gemacht werden aber ... einfach.

public static void Main(String[] args) 
{ 

    String pipedText = ""; 
    bool isKeyAvailable; 

    try 
    { 
     isKeyAvailable = System.Console.KeyAvailable; 
    } 
    catch (InvalidOperationException expected) 
    { 
     pipedText = System.Console.In.ReadToEnd(); 
    } 

    //do something with pipedText or the args 
} 
+0

Toller Trick, danke dafür! – Tao

+0

die Antwort hier von Hans Passant http://StackOverflow.com/Questions/3453220/How-To-Detect-If-Console-in-Stdin-Has-Been-Redirected am Ende, erwähnt eine noch bessere Weise 'System. Console.WriteLine (System.Console.IsInputRedirected.ToString()); ' – barlop

3

Hier ist eine andere alternative Lösung, die aus den anderen Lösungen plus einen Blick() zusammengestellt wurde.

Ohne die Peek() habe ich festgestellt, dass die App nicht ohne Strg-C am Ende zurückkehren würde, wenn Sie "t.txt | prog.exe" tun, wobei t.txt eine mehrzeilige Datei ist. Aber nur "prog.exe" oder "echo hi | prog.exe" hat gut funktioniert.

Dieser Code ist nur zur Verarbeitung von Pipe-Eingängen gedacht.

static int Main(string[] args) 
{ 
    // if nothing is being piped in, then exit 
    if (!IsPipedInput()) 
     return 0; 

    while (Console.In.Peek() != -1) 
    { 
     string input = Console.In.ReadLine(); 
     Console.WriteLine(input); 
    } 

    return 0; 
} 

private static bool IsPipedInput() 
{ 
    try 
    { 
     bool isKey = Console.KeyAvailable; 
     return false; 
    } 
    catch 
    { 
     return true; 
    } 
} 
+1

die Antwort hier von Hans Passant http://StackOverflow.com/Questions/3453220/How-To-Detect-If-Console-in-Stdin-Has -been-umgeleitet am Ende, erwähnt einen noch besseren Weg 'System.Console.WriteLine (System.Console.IsInputRedirected.ToString());' – barlop

6

Dies ist der Weg, es zu tun:

static void Main(string[] args) 
{ 
    Console.SetIn(new StreamReader(Console.OpenStandardInput(8192))); // This will allow input >256 chars 
    while (Console.In.Peek() != -1) 
    { 
     string input = Console.In.ReadLine(); 
     Console.WriteLine("Data read was " + input); 
    } 
} 

Dies ermöglicht es zwei Verwendungsmethoden. Lesen von Standardeingabe:

C:\test>myProgram.exe 
hello 
Data read was hello 

oder lesen von verrohrt Eingang:

C:\test>echo hello | myProgram.exe 
Data read was hello 
7

in .NET 4.5 es ist

if (Console.IsInputRedirected) 
{ 
    using(stream s = Console.OpenStandardInput()) 
    { 
     ... 
+0

Hallo, ich kann nicht scheinen, es funktioniert mit diesem Code, irgendwelche Ideen ? –

0

Dies funktioniert auch für

c: \ MyApp.exe < input.txt

Ich hatte einen Stringbuilder zu verwenden, um die Eingaben von stdin eingefangen zu manipulieren:

public static void Main() 
{ 
    List<string> salesLines = new List<string>(); 
    Console.InputEncoding = Encoding.UTF8; 
    using (StreamReader reader = new StreamReader(Console.OpenStandardInput(), Console.InputEncoding)) 
    { 
     string stdin; 
     do 
     { 
      StringBuilder stdinBuilder = new StringBuilder(); 
      stdin = reader.ReadLine(); 
      stdinBuilder.Append(stdin); 
      var lineIn = stdin; 
      if (stdinBuilder.ToString().Trim() != "") 
      { 
       salesLines.Add(stdinBuilder.ToString().Trim()); 
      } 

     } while (stdin != null); 

    } 
}