Вопрос

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

Это было полезно?

Решение

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

Другие советы

Я только что написал библиотеку, которая это обеспечивает, под названием «кноб» [хакерство].Вы можете использовать его для создания 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 (FFI).Я начал предлагать использовать mmap, но, поразмыслив, думаю, что mmap может быть неправильным сопоставлением, даже если вы использовали его с анонимной опцией.

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

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

Видеть /libraries/base/IOBase.lhs из источников GHC.

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

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

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

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

Чтобы добавить современный ответ на этот вопрос, вы можете использовать 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top