Схема: сериализация данных, эффективная [и функциональная] - PullRequest
3 голосов
/ 28 июля 2010

Я сериализирую данные, которые могут быть целым числом, объектом (списком) с другими вложенными объектами, и пытаюсь сделать выбор относительно того, какой подход использовать. Из двух, первый заключается в том, чтобы рекурсивно создавать байтовые векторы и копировать их в вызывающих функциях в больший одиночный байтовый вектор; второй - использовать какой-то поток, в который я мог бы написать. В конце концов, несмотря на выбор, я смогу использовать полученный двоичный массив в любой дальнейшей обработке, которая может произойти, e. г. Я бы сжал выходные данные и отправил их по сети или просто записал некоторые их части в файл.

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

Спасибо.

UPDATE:

Ниже приведены примеры, которые я добавил после того, как нашел решение, позволяющее пользователям сэкономить время на поиск способов записи данных:]

write-byte и write-bytes особенно полезны, когда вам нужно написать октеты.

> (bytes? (with-output-to-bytes (lambda () (write-byte 42))))
#t
> (bytevector? (with-output-to-bytes (lambda () (write-byte 42))))
#t
> (bytevector->u8-list (with-output-to-bytes (lambda () (write-byte 42))))
{42}
> (bytes->list (with-output-to-bytes (lambda () (write-byte 42) (write-bytes (integer->integer-bytes #x101CA75 4 #f #t)))))
(42 1 1 202 117)

Ответы [ 2 ]

4 голосов
/ 28 июля 2010

Вы можете использовать просто write для записи данных в порт. Вы можете сделать это со всеми значениями, как список, который содержит все. Может потребоваться небольшая настройка, если у вас есть проблемы, такие как циклические данные, где установка print-graph в #t будет хорошо работать И если вы хотите, чтобы вывод шел в байтовой строке, вы можете использовать open-output-bytes или удобную функцию with-output-to-bytes:

(with-output-to-bytes (lambda () (write (list value1 value2 value3))))

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

2 голосов
/ 28 июля 2010

Возможно open-bytevector-output-port - это то, что я ищу:

#lang scheme

(require rnrs/bytevectors-6)
(require rnrs/io/ports-6)

(define-values (oup ext-proc) (open-bytevector-output-port))
(write 4 oup)
(write 2 oup)
(ext-proc)
(make-bytevector 3 1)

Результат:

Добро пожаловать в DrScheme, версия 4.2.5 [3m].
Язык: scheme; memory limit: 128 MB.
#"42"
#"\1\1\1"
> 
...