ファイル ハンドルのように見えますが、実際には I/O リダイレクトに使用するインメモリ バッファーに支えられているものが必要です。これどうやってするの?
6 に答える
これを提供する「knob」[ hackage ]というライブラリを書きました。Handle
これを使用して、を参照/変更するを作成できます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)
Cまたはシステムコールの観点からやりたいことを表現できる場合は、HaskellのForeign Function Interface(FFI)を使用できます。私はmmapの使用を提案し始めましたが、匿名オプションで使用したとしても、mmapは間違った方法でマッピングされている可能性があると考えました。
Haskell FFIの詳細については、haskell.orgwikiを参照してください。
これは実際にはライブラリ設計のバグであり、私も悩まされています。私はあなたがやりたいことをするための2つのアプローチを見ていますが、どちらもひどく魅力的ではありません。
新しい型クラスを作成し、現在のハンドルをそのインスタンスにし、メモリ内データを実行する別のインスタンスを作成し、この機能を使用する必要のあるすべてのプログラムを変更します。
System.SIO
おそらくこれは、の代わりにインポート(またはあなたがそれを呼びたいもの)と同じくらい簡単ですSystem.IO
。ただし、などのライブラリでカスタムI / Oルーチンを使用する場合は、Data.ByteString
さらに多くの作業を行う必要があります。I / Oライブラリを書き直して、これをサポートするように拡張します。些細なことではなく、多くの作業が必要ですが、特に難しい作業ではありません。ただし、このライブラリがないシステムとの互換性の問題があります。
これは不可能な場合があります。GHCは、少なくとも、すべての読み取り/書き込み/シーク操作に使用されるOSファイル記述子を持つハンドルを必要としているようです。
/libraries/base/IOBase.lhs
GHCソースから参照してください。
OSのヘルプを利用することで、同じ効果を得ることができる場合があります。一時ファイルを作成し、ハンドルをそれに接続してから、I/Oリダイレクト用にファイルをメモリマップします。このようにして、すべてのハンドルI/Oがメモリマップセクションに表示されるようになります。
コンパイラを変更しないと不可能です。これは、Handle が型クラスではなく抽象データ型であるためです。