2008-09-13 82 views
13

我想要的东西看起来像一个文件句柄,但真正支持内存缓冲区以用于I/O重定向。我怎样才能做到这一点?如何在Haskell中创建内存中的句柄?

+0

你可能想重新回顾这个问题,你应该看到一个新的答案。 – 2011-10-10 20:07:12

+0

@Peter Mortensen看来约翰的答案正是你想要的。 – PyRulez 2015-03-31 21:18:02

回答

0

不修改编译器是不可能的。这是因为Handle是一个抽象数据类型,而不是一个类型类型。

1

这可能是不可能的。至少,GHC似乎需要一个句柄才能拥有用于所有读/写/查找操作的OS文件描述符。

查看来自GHC源的/libraries/base/IOBase.lhs

您可以通过获得操作系统的帮助来获得相同的效果:创建一个临时文件,将句柄连接到它,然后为I/O重定向映射文件。这样,所有的句柄I/O都将在内存映射部分中可见。

3

如果你可以用C或系统调用表达你想要做的事情,你可以使用Haskell的外部函数接口(FFI)。我开始建议使用mmap,但是第二个想法是我认为即使您使用匿名选项,mmap也可能是错误的映射。

您可以在haskell.org wiki上找到关于Haskell FFI的更多信息。

1

这实际上是图书馆设计中的一个错误,也是令我烦恼的一个错误。我看到两种方法可以做你想做的事,而这两种方法都不是非常有吸引力。

  1. 创建一个新的类型类,使当前处理它的一个实例,写另一个实例做内存数据的事情,并改变所有的程序需要使用此功能的。可能这与输入System.SIO(或任何你想称之的)而不是System.IO一样简单。但是,如果您在库中使用自定义I/O例程(例如Data.ByteString),那么需要完成更多工作。

  2. 重写I/O库以扩展它们以支持此操作。不是微不足道的,还有很多工作,但这不是特别困难的工作。然而,那么你对没有这个库的系统有兼容性问题。

19

我刚刚写了一个图书馆,提供了这个,称为“旋钮”[hackage]。您可以使用它来创建Handle S的引用/修改ByteString

import Data.ByteString (pack) 
import Data.Knob 
import System.IO 

main = do 
    knob <- newKnob (pack []) 
    h <- newFileHandle knob "test.txt" WriteMode 
    hPutStrLn h "Hello world!" 
    hClose h 
    bytes <- Data.Knob.getContents knob 
    putStrLn ("Wrote bytes: " ++ show bytes)