如何用Delphi 7查看STDIN?
在 Delphi 7 控制台应用程序中,如何检查 stdin 是否包含一个字符,而不阻塞直到输入一个字符?
我的计划是这个控制台程序将由 GUI 程序执行,并且它的标准输入将由 GUI 程序写入。
所以我希望我的控制台应用程序定期检查标准输入,但我找不到一种不阻塞的方法。
我看过 这个答案,这让我得到一个指向标准输入的流,但据我所知仍然无法“查看”。
In a Delphi 7 console application, how can I check whether stdin holds a character, without blocking until one is entered?
My plan is that this console program will be executed by a GUI program, and its stdin will be written to by the GUI program.
So I want my console app to periodically check stdin, but I can't find a way of doing this without blocking.
I have looked at this answer, which gets me a stream pointing to stdin, but there's still no way to "peek" as far as I can see.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为您已经找到了阅读 stdin 的正确方法。当没有更多内容可读时,它会被阻塞。
处理这个问题的标准方法是使用单独的线程来处理管道。当它从标准输入接收到新数据时,它会向处理线程发出信号,例如使用消息传递机制。
话虽如此,如果您确实想轮询,可以调用 PeekNamedPipe 来检查管道中是否有数据。
I think you have already found the right way to read stdin. It is meant to block when there's nothing more to be read.
The standard way to handle this is to use a separate thread to handle the pipe. When it receives new data from stdin it signals this to the processing thread, for example with a message passing mechanism.
Having said all that, if you really want to poll you can call PeekNamedPipe to check if there is data in the pipe.
您可以像其他答案所说的那样使用线程,但即使如此,您也可能会遇到问题(使用线程方法),除非您还调查重叠 IO。
我通常使用串行端口而不是标准输入的重叠 IO,其中通常需要“如果准备好则读取一个字符”,并且非阻塞 IO 是一种常见的工作方式。您应该能够采用此处所示的技术。但是,如果我正在编写一个由键盘驱动的应用程序(而不是纯粹由重定向到标准输入的文件驱动),我会放弃 StdIN,并使用 CRT 类型单元。因此,如果您不介意放弃 StdIn,并且只是想要一个键盘驱动的输入模型,那么您可以查看基于控制台的 API,并放弃非常有限的 StdIn 功能。有关使用 Win32 控制台 API 的“kbhit”函数的示例,请参阅
You could as the other answer says use threads, but even then you might have problems (using the threading method) unless you also investigate overlapped IO.
I normally use overlapped IO with serial ports rather than stdin, where "read a character if one is ready" is commonly needed, and where non-blocking IO is a usual way of working. You should be able to adapt the technique shown here. However, if I was writing an application that was keyboard driven (instead of purely driven by say, a file redirected to standard input) I would let go of StdIN, and use a CRT type unit. So, if you don't mind letting go of StdIn, and simply want to have a keyboard-driven input model, you could look at console based APIs and abandon the very limiting StdIn capabilities. For an example of a "kbhit" function that uses the Win32 Console APIs see here.
没有其他方法(据我所知),可以从单独线程内的管道读取。否则,正如您已经看到的,读取文件操作将被阻塞。我写了一个示例如何执行此操作,还提供了一个示例项目: 重定向 stdoutput
编辑:好吧,再次阅读您的问题,我知道您的问题出在控制台程序中,而不是调用应用程序中。我想知道您的控制台应用程序期望什么,通常控制台应用程序知道何时需要输入,并且在用户输入此信息之前无法继续。需要检查出口吗?
There is no other way (as far as i know), as reading from a pipe inside a separate thread. Otherwise as you already have seen, the readfile operation will block. I wrote an example how to do this, an example project is also available: redirect stdoutput
Edit: Well, reading your question another time, i understand that your problem lies within the console program, not the calling application. I wonder what your console application expects, normally a console application knows when it needs input and cannot proceede until the user enters this information. Do you need to check for an exit?
对于流,如果您 .Read() ,函数结果是读取的字节数,如果没有任何内容,即使您要求更多字节数,该数也将为零。来自 Classes.TStream.Read 的 Delphi 帮助:
For a Stream if you .Read() the function result is the number of bytes read which will be zero if there was nothing there even if you asked for more. From the Delphi help for Classes.TStream.Read: