在Delphi中读取标准输入流的程序

9

I have the following batch script:

dir | myapp.exe

这个程序的源代码(或多或少)如下:

procedure TForm1.FormCreate(Sender: TObject);
var buff: String;
begin
  Read(buff);
  Memo1.Lines.Text:=buff;
end;

在备忘录中的输出结果是:

驱动器 C 中的卷没有标签。

我尝试过:

  • 将读取部分放入一个循环中,以 eof 作为条件 - 但会导致无限循环
  • 编写一个循环,一直读取,直到 strlen(buff) 为 0 - 却出现了第二次退出的情况
  • 每隔 0.5 秒读取一些东西(我考虑异步写入 stdin),但也失败了

顺便说一下,直接运行程序而不输入 stdin 数据会导致 EInputOutput 异常(I/O 错误)代码 6。

2个回答

12

GUI应用程序不会自动分配标准输入、标准输出或标准错误流。你可以这样做:

procedure TForm1.FormCreate(Sender: TObject);
var
  Buffer: array[0..1000] of Byte;
  StdIn: TStream;
  Count: Integer;
begin
  StdIn := THandleStream.Create(GetStdHandle(STD_INPUT_HANDLE));
  Count := StdIn.Read(Buffer, 1000);
  StdIn.Free;
  ShowMessageFmt('%d', [Count]);
end;

如果你这样做

dir *.pas | myapp.exe

你将会看到一个数字大于0的消息框,如果你这样做:

myapp.exe

您将看到一个带有0的消息框。两种情况下,表单都将被显示。


好的,这个很好运行!我继续读取直到 Count < sizeOf(Buffer) 吗? - Christian
是的,请继续阅读,直到 Count < Sizeof(Buffer)。请注意,缓冲区不一定以零结尾,因此请使用例如 TMemoryStream 将缓冲区添加到其中,并最终在末尾添加 #0,以便您可以将其作为字符串读取。 - Rudy Velthuis
顺便说一句,虽然我在这里回答问题,但我大多数时间都是来学习的。特别是Objective-C,还有C、C++以及算法等方面的知识。 - Rudy Velthuis

4

尝试使用流式处理而不是 Read(buff) 方法。

InputStream := THandleStream.Create(GetStdHandle(STD_INPUT_HANDLE));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接