Pergunta

Eu estou escrevendo um programa que executa um processo sub externo de forma interativa e eu preciso o conteúdo da alça de saída para ser a saída para stdout assim que ele estiver disponível. Eu tentei algo como isto:

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

Mas isso não funciona, uma vez que só reconhece linha de saída por linha, de modo que qualquer saída na alça de saída processos que não é terminada por uma nova linha não aparecer. Eu tentei a mesma coisa com hGetContents mas produz o mesmo resultado. Eu li a documentação de ambos System.Process e System.IO e realmente não encontrei nada conclusivo.

Foi útil?

Solução

hSetBuffering é o que você está procurando, o padrão (em Unix, pelo menos) é a linha de buffering. Use-o sobre a stdin antes de iniciar o loop principal

hSetBuffering hIn NoBuffering

e opcionalmente também no punho saída se você quiser ver os resultados imediatamente no lado de saída. Note, no entanto, que a desativação buffer pode diminuir drasticamente o desempenho.

Outras dicas

Eu sou muito mais um novato Haskell, mas lembro-me vir através de um exemplo recente de processamento do personagem-by-entrada. É hSetBuffering possivelmente o que você está procurando?

Buffer é uma coisa, mas você também está usando gGetLine que irá esperar por uma linha inteira (ou fim de arquivo). Considere o uso de hGetChar se você realmente quer ler um caractere no momento. E btw, uma outra maneira de superar o buffer é usar hFlush.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top