Data.Binary
| Авторские права | Lennart Kolmodin |
|---|---|
| Лицензия | BSD3-style (см. LICENSE) |
| Поддержка | Lennart Kolmodin <kolmodin@gmail.com> |
| Стабильность | нестабильная |
| Переносимость | переносимая на Hugs и GHC. Требует FFI и некоторые гибкие экземпляры. |
| Безопасный Haskell | Достоверный |
| Язык | Haskell98 |
Содержание
Описание
Бинарная сериализация значений Haskell в ленивые ByteString и из них. Библиотека Binary предоставляет методы для кодирования значений Haskell в виде потоков байтов непосредственно в памяти. Полученные ByteString затем можно записать на диск, отправить по сети или дополнительно обработать (например, сжать с помощью gzip).
Пакет binary примечателен тем, что он предоставляет как чистую, так и высокопроизводительную сериализацию.
Значения, закодированные с помощью класса Binary, всегда кодируются в сетевом порядке (big endian), и закодированные данные должны быть переносимы через разрядность машины, размер слова или версию компилятора. Например, данные, закодированные с помощью класса Binary, можно было бы записать на любой машине и считать обратно на любую другую.
Если конкретный формат данных для вас не важен, например, вас больше интересует сериализация и десериализация значений, чем формат, который будет использован, можно вывести экземпляры Binary с использованием поддержки обобщенных типов. См. GBinary.
Если у вас есть конкретные требования к формату кодирования, вы можете использовать примитивы кодирования и декодирования напрямую, см. модули Data.Binary.Get и Data.Binary.Put.
Класс Binary
class Binary t where Исходный код
Класс Binary предоставляет методы для кодирования и декодирования значения Haskell в ленивый ByteString. Он отражает классы Read и Show для текстового представления типов Haskell и подходит для сериализации значений Haskell на диск или через сеть.
Для декодирования и генерации простых внешних двоичных форматов (например, структур C) можно использовать Binary, но в целом он не подходит для сложных протоколов. Вместо этого используйте примитивы Put и Get напрямую.
Экземпляры Binary должны удовлетворять следующему свойству:
decode . encode == id
То есть, методы get и put должны быть обратными друг другу. Для базовых типов Haskell предоставляется ряд экземпляров.
Минимальное полное определение
Nothing
Методы
put :: t -> Put Исходный код
Кодирование значения в монаде Put.
get :: Get t Исходный код
Декодирование значения в монаде Get
Экземпляры
Пример
Для сериализации пользовательского типа требуется экземпляр Binary для этого типа. Например, предположим, что у нас есть структура данных:
data Exp = IntE Int
| OpE String Exp Exp
deriving Show
Мы можем кодировать значения этого типа в байтовые строки, используя следующий экземпляр, который рекурсивно разбивает структуру для сериализации:
instance Binary Exp where
put (IntE i) = do put (0 :: Word8)
put i
put (OpE s e1 e2) = do put (1 :: Word8)
put s
put e1
put e2
get = do t <- get :: Get Word8
case t of
0 -> do i <- get
return (IntE i)
1 -> do s <- get
e1 <- get
e2 <- get
return (OpE s e1 e2)
Обратите внимание, как мы записываем начальный байт тега, чтобы указать каждый вариант типа данных.
Мы можем упростить запись экземпляров get с помощью монадических комбинаторов:
get = do tag <- getWord8
case tag of
0 -> liftM IntE get
1 -> liftM3 OpE get get get
Чтобы сериализовать это в байтовую строку, мы используем encode, которая упаковывает структуру данных в бинарный формат, в ленивую байтовую строку
> let e = OpE "*" (IntE 7) (OpE "/" (IntE 4) (IntE 2)) > let v = encode e
Где v - это бинарно закодированная структура данных. Чтобы восстановить исходные данные, мы используем decode
> decode v :: Exp OpE "*" (IntE 7) (OpE "/" (IntE 4) (IntE 2))
ленивая ByteString, которая получается из encode, может быть записана на диск и прочитана с диска с помощью функций Data.ByteString.Lazy IO, таких как hPutStr или writeFile:
> writeFile "/tmp/exp.txt" (encode e)
И прочитать обратно с помощью:
> readFile "/tmp/exp.txt" >>= return . decode :: IO Exp OpE "*" (IntE 7) (OpE "/" (IntE 4) (IntE 2))
Мы также можем напрямую сериализовать значение в Handle или файл и из них:
> v <- decodeFile "/tmp/exp.txt" :: IO Exp OpE "*" (IntE 7) (OpE "/" (IntE 4) (IntE 2))
И записать значение на диск
> encodeFile "/tmp/a.txt" v
Универсальная поддержка
Начиная с GHC 7.2, можно использовать бинарную сериализацию без написания какого-либо кода шаблона экземпляра.
{-# LANGUAGE DeriveGeneric #-}
import Data.Binary
import GHC.Generics (Generic)
data Foo = Foo
deriving (Generic)
-- GHC will automatically fill out the instance
instance Binary Foo
Этот механизм использует эффективную встроенную поддержку универсалов GHC.
Монады Get и Put
Примеры
Put просто поднимает Builder в монаду Writer, применённую к ().
Полезные вспомогательные функции для написания примеров
putWord8 :: Word8 -> Put Source
Эффективно записывает байт в буфер вывода
Чтение Word8 из состояния монады
Бинарная сериализация
encode :: Binary a => a -> ByteString Source
Кодирование значения с помощью бинарной сериализации в ленивую ByteString.
decode :: Binary a => ByteString -> a Source
Декодирование значения из ленивой ByteString, восстанавливая исходную структуру.
decodeOrFail :: Binary a => ByteString -> Either (ByteString, ByteOffset, String) (ByteString, ByteOffset, a) Source
Декодирование значения из ленивой ByteString. Возвращает Left при неудаче и Right при успехе. В обоих случаях возвращаются неиспользованный вход и количество прочитанных байтов. В случае неудачи также возвращается удобочитаемое сообщение об ошибке.
Функции IO для сериализации
encodeFile :: Binary a => FilePath -> a -> IO () Source
Лениво сериализует значение в файл.
Это просто удобная функция, она определена как:
encodeFile f = B.writeFile f . encode
Например, если вам нужно сжатие, можно использовать:
B.writeFile f . compress . encode
decodeFile :: Binary a => FilePath -> IO a Source
Декодирование значения из файла. В случае ошибок, error будет вызвана с сообщением об ошибке.
decodeFileOrFail :: Binary a => FilePath -> IO (Either (ByteOffset, String) a) Source
Декодирование значения из файла. В случае успеха, значение будет возвращено в Right. В случае ошибок декодера, сообщение об ошибке вместе со смещением байта будут возвращены.
module Data.Word
© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/7.10.3/docs/html/libraries/binary-0.7.5.0/Data-Binary.html