Как создать дескриптор в памяти в Haskell? - PullRequest
13 голосов
/ 13 сентября 2008

Я хочу что-то похожее на дескриптор файла, но на самом деле оно поддерживается буфером в памяти, чтобы использовать его для перенаправления ввода / вывода. Как я могу это сделать?

Ответы [ 6 ]

19 голосов
/ 09 октября 2011

Я только что написал библиотеку, которая предоставляет это, называемую "knob" [ 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)
3 голосов
/ 16 сентября 2008

Если вы можете выразить то, что вы хотите сделать, в терминах C или системных вызовов, вы можете использовать интерфейс внешних функций Haskell (FFI). Я начал предлагать использовать mmap, но подумав, я думаю, что mmap может отображаться неправильно, даже если вы использовали его с анонимной опцией.

Более подробную информацию о Haskell FFI можно найти на вики haskell.org.

1 голос
/ 26 июня 2009

Это на самом деле ошибка в дизайне библиотеки, и она меня тоже раздражает. Я вижу два подхода к тому, что ты хочешь, но ни один из них не очень привлекателен.

  1. Создайте новый класс типов, сделайте текущий дескриптор его экземпляром, напишите другой экземпляр для выполнения операции с данными в памяти и измените все ваши программы, которые должны использовать это средство. Возможно, это так же просто, как импортировать System.SIO (или как вы хотите это называть) вместо System.IO. Но если вы используете пользовательские подпрограммы ввода / вывода в библиотеках, таких как Data.ByteString, там будет еще много работы.

  2. Перепишите библиотеки ввода-вывода, чтобы расширить их для поддержки этого. Не тривиально, и много работы, но это не будет особенно трудной работой. Однако тогда возникает проблема совместимости с системами, в которых эта библиотека отсутствует.

1 голос
/ 15 сентября 2008

Это может быть невозможно. GHC , по крайней мере, требует, чтобы дескриптор имел дескриптор файла ОС, который используется для всех операций чтения / записи / поиска.

См. /libraries/base/IOBase.lhs из источников GHC.

Вы можете получить тот же эффект, обратившись к справке ОС: создайте временный файл, подключите к нему дескриптор, а затем сопоставьте файл памяти для перенаправлений ввода / вывода. Таким образом, весь дескриптор ввода-вывода станет видимым в разделе отображения памяти.

0 голосов
/ 10 января 2018

Чтобы добавить современный ответ на этот вопрос, вы можете использовать createPipe из System.Process:

createPipe :: IO (Handle, Handle)

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

0 голосов
/ 16 сентября 2008

Это невозможно без изменения компилятора. Это потому, что Handle - это абстрактный тип данных, а не класс типов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...