2008-09-13 26 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)