ハスケル:どのようにリアルタイムで他にパイプ1つのハンドルの内容をします

StackOverflow https://stackoverflow.com/questions/671610

  •  21-08-2019
  •  | 
  •  

質問

私は対話的に外部のサブプロセスを実行し、私は、すぐにそれが利用可能であるとして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を使用することです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top