Frage

Ich mag etwas, das wie eine Datei-Handle sieht aber wirklich durch einen in-Speicherpuffer gesichert verwenden, um E / A-umleitet. Wie kann ich das tun?

War es hilfreich?

Lösung

Es ist nicht möglich, ohne den Compiler zu modifizieren. Dies liegt daran, Handle ein abstrakter Datentyp ist, kein typeclass.

Andere Tipps

Ich schrieb eine Bibliothek, die diese bietet, genannt "Knopf" [ Hackage ]. Sie können es verwenden Handles die Bezug zum Erstellen / Ändern einer 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)

Wenn Sie sagen, was Sie in Bezug auf C tun wollen oder System ruft Sie Haskells Foreign Function Interface (FFI) nutzen könnten. Ich begann Mmap vorschlagen verwenden, aber auf dem zweiten Gedanken denke ich Mmap eine Abbildung der falsche Weg sein könnte, auch wenn Sie es mit der anonymen Option verwendet wird.

Sie können mehr Informationen über die Haskell FFI im haskell.org Wiki finden.

Das kann nicht möglich sein. GHC , zumindest scheint ein Handle zu erfordern ein OS Dateideskriptor zu haben, die für verwendet wird alle Lese- / Schreib- / Suchoperationen.

Siehe /libraries/base/IOBase.lhs von den GHC Quellen.

Unter Umständen können Sie den gleichen Effekt erhalten, indem die Hilfe des OS Anwerbung: eine temporäre Datei erstellen, eine Verbindung zu dem Griff und dann die Datei-Speicherkarte für die I / O-umleitet. Auf diese Weise alle den Griff I / O würde im Speicher abgebildeten Abschnitt sichtbar werden.

Dies ist tatsächlich ein Fehler in der Bibliothek Design, und eine, die mich auch geärgert hat. Ich sehe zwei Ansätze zu tun, was Sie wollen, von denen keiner furchtbar attraktiv ist.

  1. Erstellen Sie eine neue typeclass, die aktuelle Griff machen eine Instanz davon, schreiben eine andere Instanz die In-Memory-Daten Sache zu tun, und alle Programme ändern, die diese Einrichtung verwenden müssen. Möglicherweise ist dies so einfach wie das Importieren System.SIO (oder was auch immer Sie es nennen wollen) statt System.IO. Aber wenn Sie die benutzerdefinierte verwenden I / O-Routinen in Bibliotheken wie Data.ByteString, gibt es mehr Arbeit dort getan werden.

  2. Schreiben Sie die I / O-Bibliotheken, sie zu verlängern, dies zu unterstützen. Nicht trivial, und eine Menge Arbeit, aber es wäre nicht besonders schwierig, Arbeit zu tun. Aber dann haben Sie ein Kompatibilitätsproblem mit Systemen bekommen, die diese Bibliothek nicht hat.

Um eine moderne Antwort auf diese Frage hinzufügen, können Sie createPipe von System.Process verwenden:

createPipe :: IO (Handle, Handle)

https: / /www.stackage.org/haddock/lts-10.3/process-1.6.1.0/System-Process.html#v:createPipe

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top