ハスケル:どのようにリアルタイムで他にパイプ1つのハンドルの内容をします
質問
私は対話的に外部のサブプロセスを実行し、私は、すぐにそれが利用可能であるとして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両方のドキュメントを読んでいると、本当に決定的な何かを発見していない。
解決
hSetBuffering
は、あなたが(Unix上で少なくとも)行バッファリングでデフォルト、探しているものです。メインループを開始する前に、標準入力の上、それを使用してください。
hSetBuffering hIn NoBuffering
と、必要に応じても、あなたは、出力側ですぐに結果を確認したい場合は、出力ハンドルに。バッファリングを無効にすると、かなり大幅にパフォーマンスが低下することができること、しかし、注意します。
他のヒント
私は非常にHaskellの初心者だけど、私は、入力文字ずつ処理するの最近の例に出くわす覚えています。ある hSetBuffering の可能性が何を探してるんですか?
バッファリングは、一つのことですが、あなたはまた、行全体(またはファイルの末尾)を待ちますgGetLine
を使用しています。あなたが本当に一度に1つの文字を読みたい場合はhGetChar
の使用を検討してください。
そしてところで、バッファリングを克服する別の方法は、hFlush
を使用することです。
所属していません StackOverflow