Haskell默认io缓冲 [英] Haskell default io buffering

查看:141
本文介绍了Haskell默认io缓冲的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



为了学习新东西,我试图实现一个Haskell解决方案。微不足道的 main = forever $ interact reverse 不起作用。我经历了这个问题,并做出了一个更正的版本:

  import Control.Monad 
import System.IO

main = forever $ interact revLines

revLines = unline。地图(反向)。行

但是这个修正版本也行不通。我阅读了缓冲文档和各种设置玩。
如果我设置 NoBuffering LineBuffering ,我的程序可以正常工作。最后,我打印出stdin和stdout的默认缓冲模式。

  import System.IO 

main = do
hGetBuffering stdin>> = print
hGetBuffering stdout>> = print

如果我从xinetd运行程序( echotest| nc localhost 7 ),我得到 BlockBuffering Nothing c>)但从cli我有 LineBuffering




  • 有什么区别在xinetd tcp服务和cli程序之间,关于缓冲?

  • 如果我想用两种运行方法编写工作程序,是否必须手动设置缓冲?






编辑:谢谢大家的有用答案。



我接受了火焰给出的答案,他给我一个提示isatty(3)。我再次检查了System.IO文档,发现 hIsTerminalDevice 函数,以至于我能够检查句柄的连接。



为了记录,这里是我的最终程序:

  { - #OPTIONS_GHC -W# - } 

import System.IO

main = do
hSetBuffering stdin LineBuffering
hSetBuffering stdout LineBuffering

interact revLines

revLines = unlines。地图(反向)。行


解决方案

它不是特定于Haskell(例如标准C库做同样的事情)。
传统上,如果文件描述符对应于终端,则缓冲设置为行模式,否则为阻止模式。文件描述符类型可以通过 isatty(3)函数进行检查 - 不确定它是否被导出到 System.IO

是的,如果你依赖它,你需要手动设置缓冲模式。



由方式,你可以通过运行你的程序作为 cat | cheat来欺骗系统,并在命令行中强制阻止缓冲。 ./prog |猫


Yesterday i wrote a little xinetd exercise for my students: make a reverse echo program.

To learn something new, i tried to implement a Haskell solution. The trivial main = forever $ interact reverse does not work. I went through this question and made a corrected version:

import Control.Monad
import System.IO

main = forever $ interact revLines

revLines = unlines . map (reverse) . lines 

But this corrected version also doesn't work. I read the buffering documentation and played with the various settings. If i set NoBuffering or LineBuffering, my program works correctly. Finally i printed out the default buffering modes for stdin and stdout

import System.IO

main = do 
  hGetBuffering stdin >>= print 
  hGetBuffering stdout >>= print

I've got BlockBuffering Nothing if i run my program from xinetd(echo "test" | nc localhost 7) but from cli i've got LineBuffering

  • What is the difference between a xinetd tcp service and a cli program, regards to buffering?
  • Do i have to set manually the buffering if i want to write a working program with both running method?

Edit: Thank you all for the helpful answers.

I accept the answer which was given by blaze, he give me a hint with isatty(3). I went through again the System.IO documentation and found the hIsTerminalDevice function, with wich i am able to check the connection of the handle.

For the record, here is my final program:

{-# OPTIONS_GHC -W #-}

import System.IO

main = do
  hSetBuffering stdin LineBuffering
  hSetBuffering stdout LineBuffering

  interact revLines

revLines = unlines . map (reverse) . lines 

解决方案

It's not specific to Haskell (e.g. the standard C library does the same thing). Traditionally, if a file descriptor corresponds to the terminal, buffering is set to line mode, otherwise to block mode. File descriptor type can be checked by the isatty(3) function -- not sure if it is exported to System.IO.

And yes, you need to set buffering mode manually if you depend on it.

By the way, you can cheat the system and force block buffering in the command line by running your program as cat | ./prog | cat.

这篇关于Haskell默认io缓冲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆