Haskell:如何将一个句柄的内容实时传输到另一个句柄中

时间:2009-03-22 21:02:26

标签: haskell io monads

我正在编写一个以交互方式运行外部子进程的程序,我需要输出句柄的内容一旦可用就输出到stdout。我尝试过这样的事情:

main = do processInfo <- createProcess (proc "ghci" []){std_out = CreatePipe,
                                                    std_in  = CreatePipe }
       case processInfo of
          (Just hIn, Just hOut, _, _) -> do mainloop hIn hOut
                                          hClose hIn
                                          hClose hOut
       _                              -> do error "Unable to start process"

mainloop :: Handle -> Handle -> IO ()
mainloop inh outh = 
    do ineof <- hIsEOF outh
       if ineof
          then return ()
          else do inpStr <- hGetLine outh
                  putStrLn inpStr
                  mainloop inh outh

但这不起作用,因为它只能逐行识别输出,因此不会显示未由换行符终止的进程输出句柄上的任何输出。我用hGetContents尝试了同样的事情,但它产生了相同的结果。我已经阅读了System.Process和System.IO的文档,并没有真正找到任何结论。

3 个答案:

答案 0 :(得分:4)

hSetBuffering是您正在寻找的,默认(至少在Unix上)是行缓冲。在启动主循环之前在stdin上使用它

hSetBuffering hIn NoBuffering
如果要在输出端立即查看结果,还可以选择输出句柄

。但请注意,禁用缓冲可能会极大地降低性能。

答案 1 :(得分:2)

我是一个Haskell新手,但我记得最近遇到了一个逐个处理输入的例子。 hSetBuffering可能正是您要找的吗?

答案 2 :(得分:0)

缓冲是一回事,但你也在使用等待整行(或文件结尾)的gGetLine。如果您真的想在当时读取一个字符,请考虑使用hGetChar。 顺便说一下,克服缓冲的另一种方法是使用hFlush