2008-10-14 13 views

Respuesta

37

Necesita usar Console.Read() y Console.ReadLine() como si estuviera leyendo la entrada del usuario. Las tuberías reemplazan la entrada del usuario de forma transparente. No puedes usar ambos fácilmente (aunque estoy seguro de que es bastante posible ...).

Editar:

Un simple programa de cat estilo:

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

    } 
} 

Y cuando se ejecuta, como era de esperar, la salida:

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

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

Su ejemplo funciona para: echo "Foo bar baz" | ConsoleApplication1.exe | ConsoleApplication1.exe? –

+2

Sí. Usando una analogía de nivel inferior, lo que realmente sucede con una tubería es que la corriente de Stdout de la primera aplicación se conecta a la corriente Stdin de la siguiente aplicación en la tubería. El stdin de la consola se pasa a través de la primera aplicación y se muestra la última solicitud stdout. –

+0

¡Tommorow intentaré eso! Thx :) –

2

Console.In es una referencia a una TextReader envuelto alrededor de la corriente de entrada estándar. Al canalizar grandes cantidades de datos a su programa, podría ser más fácil trabajar de esa manera.

1

hay un problema con el ejemplo proporcionado.

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

va pegado a la espera de entrada si se puso en marcha el programa sin datos de tuberías. así que el usuario tiene que presionar manualmente cualquier tecla para salir del programa.

+0

que es más digno como un comentario, y otros han abordado eso y una solución al mismo – barlop

13

Lo siguiente no suspenderá la aplicación para la entrada y funciona cuando los datos son o no está canalizado. Un poco de un truco; y debido a la captura de errores, el rendimiento podría faltar cuando se realizan numerosas llamadas por canal, pero ... fácil.

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

¡Gran truco, gracias por esto! – Tao

+0

la respuesta aquí por hans passant http://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected near the end, menciona una forma aún mejor 'System. Console.WriteLine (System.Console.IsInputRedirected.ToString()); ' – barlop

3

Aquí hay otra solución alternativa que se armó a partir de las otras soluciones más un vistazo().

Sin The Peek() Estaba pasando por la sensación de que la aplicación no volvería sin ctrl-c al final al hacer "tipo t.txt | prog.exe" donde t.txt es un archivo de varias líneas. Pero solo "prog.exe" o "echo hi | prog.exe" funcionó bien.

este código está destinado a procesar solo la entrada canalizada.

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

la respuesta aquí por hans passant http://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has -ser redirigido cerca del final, menciona una forma aún mejor 'System.Console.WriteLine (System.Console.IsInputRedirected.ToString());' – barlop

6

Esta es la manera de hacerlo:

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

Esto permite que dos métodos de uso. Leer desde la entrada estándar :

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

o leer por tubería de entrada:

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

en .NET 4.5 es

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

Hola, parece que no puedo hacerlo funcionar con este código, cualquier idea ? –

0

Esto también funciona para

c: \ MyApp.exe < entrada.txt

tuviera que utilizar un StringBuilder para manipular las entradas capturados de la entrada estándar:

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

    } 
} 
Cuestiones relacionadas