2008-10-14 2 views

ответ

37

Вам необходимо использовать Console.Read() и Console.ReadLine(), как если бы вы читали пользовательский ввод. Трубы прозрачно заменяют вход пользователя. Вы не можете использовать оба легко (хотя я уверен, что это вполне возможно ...).

Edit:

Простая программа cat стиль:

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

    } 
} 

И при запуске, как и ожидалось, выход:

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

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

В вашем примере работает: echo "Foo bar baz" | ConsoleApplication1.exe | ConsoleApplication1.exe? – 2008-10-14 00:41:29

+2

Да. Используя аналогию с более низким уровнем, то, что действительно происходит с трубой, является поток Stdout первого приложения, который подключается к потоку Stdin следующего приложения в конвейере. Консоль stdin получает первое приложение, и отображаются последние stdout приложения. – 2008-10-14 00:44:40

+0

Tommorow Я попробую это !!! Thx :) – 2008-10-14 00:48:54

2

Console.In является ссылкой на TextReader обернут вокруг стандартного потока ввода. При передаче больших объемов данных в вашу программу может быть проще работать с этим путем.

1

есть проблема с прилагаемым примером.

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

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

13

Неприменимо к приложению для ввода и работает, когда данные или не передаются по трубопроводам. Немного взлома; и из-за ошибки ловушки, производительность может отсутствовать, когда многочисленные звонки по каналам сделаны, но ... легко.

3

Вот еще одно альтернативное решение, которое было составлено из других решений, а также заглянуть().

Без Peek() У меня возникло ощущение, что приложение не будет возвращаться без ctrl-c в конце, когда вы делаете «tttt.txt» prog.exe, где t.txt является многострочным файлом. Но просто «prog.exe» или «echo hi | prog.exe» отлично работали.

Этот код предназначен только для обработки входных данных по трубопроводам.

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

Это способ сделать это:

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

Это позволяет два способа использования. Чтение из стандартного ввода :

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

или читать из водопроводной вход:

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

в .NET 4.5 это

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

Это также будет работать для

C: \ MyApp.exe < input.txt

Я должен был использовать StringBuilder для управления входами, захваченные из STDIN:

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

    } 
}