Haskell: Comment tuyau le contenu d'une poignée dans une autre en temps réel

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

  •  21-08-2019
  •  | 
  •  

Question

Je suis en train d'écrire un programme qui fonctionne de manière interactive un sous-processus externe et j'ai besoin le contenu de la poignée de sortie pour être STDOUT dès qu'il est disponible. J'ai essayé quelque chose comme ceci:

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

Mais cela ne fonctionne pas, car il ne reconnaît que la ligne de sortie par ligne, de sorte que toute sortie sur le processus poignée de sortie qui ne se termine pas par un saut de ligne ne se présente pas. J'ai essayé la même chose avec hGetContents mais elle produit le même résultat. J'ai lu dans la documentation des deux système.Procédé et System.IO et n'ont pas vraiment trouvé rien de concluant.

Était-ce utile?

La solution

hSetBuffering est ce que vous cherchez, la valeur par défaut (sous Unix au moins) est mise en mémoire tampon de ligne. Il permet à l'entrée standard avant de commencer la boucle principale

hSetBuffering hIn NoBuffering

et éventuellement aussi sur la poignée de sortie si vous voulez voir les résultats immédiatement sur le côté de sortie. Notez toutefois que la désactivation de mise en mémoire tampon peut diminuer considérablement les performances tout à fait.

Autres conseils

Je suis un débutant beaucoup Haskell, mais je me souviens à venir à travers un exemple récemment de traitement de caractère par caractère d'entrée. hSetBuffering peut-être ce que vous cherchez?

est Buffering une chose, mais vous utilisez aussi qui attendra gGetLine pour une ligne entière (ou la fin du fichier). Pensez à utiliser si vous voulez hGetChar vraiment lire un caractère à l'époque. Et d'ailleurs, une autre façon de surmonter en mémoire tampon est d'utiliser hFlush.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top