3

Je suis en train de sérialiser des données qui peuvent être un entier, un objet (liste) avec d'autres objets imbriqués, et d'essayer de faire un choix quant à l'approche à utiliser. Parmi les deux, le premier consiste à créer des bytevectors de manière récursive et à les copier dans les fonctions d'appel vers un plus grand bytevector; le second est d'utiliser une sorte de flux que je pourrais écrire. Finalement, nonobstant le choix, je serais en mesure d'utiliser le tableau binaire résultant dans tout autre traitement qui pourrait se produire, e. g. Je voudrais compresser les données de sortie et l'envoyer via le réseau ou juste écrire certaines parties de celui-ci dans un fichier. Je voudrais rester fonctionnel (ou complètement) en implémentant le sérialiseur rapide. J'utilise Racket, bien que toute autre implémentation Scheme le fera aussi.Schéma: sérialisation des données, efficace [et fonctionnel]

Merci.

MISE À JOUR:

Voici les exemples que j'ai ajouté après avoir trouvé une solution pour que les utilisateurs économisent du temps à chercher le chemin quant à la façon d'écrire des données:]

write-byte et write-bytes sont d'utilisation particulière lorsque vous avez besoin d'écrire des octets.

> (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) 

Répondre

4

Vous pouvez simplement utiliser write pour écrire les données à un port. Vous pouvez le faire avec toutes les valeurs, comme une liste qui contient tout. Il se peut que vous ayez besoin d'ajustements mineurs au cas où vous auriez des problèmes tels que des données cycliques, où le réglage print-graph à #t le traitera correctement. Et si vous voulez que la sortie pour aller à une chaîne d'octets, vous pouvez utiliser open-output-bytes, ou la fonction with-output-to-bytes pratique:

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

Ce ne va pas être aussi compact que d'une représentation binaire - mais si vous prévoyez sur la compression de la sortie de toute façon, peu importe.

+0

'with-output-to-bytes' et les amis créent généralement un port de sortie et appellent proc [avec ce port comme argument unique]. Cependant - au cas où j'utiliserais votre approche - j'aimerais pouvoir passer tous les autres arguments à mon proc personnalisé comme cela est fait dans mon implémentation actuelle http://paste.lisp.org/display/113007 (proc ' write-any'). –

+0

Non, 'with-output-to-bytes' attend un * thunk * - une fonction sans argument. En ce qui concerne les arguments, Scheme a une portée lexicale, et cette fonction peut utiliser tous les noms liés. –

+0

Je suppose que ma fonction ne sera plus un combinateur si je vais dans ce sens, car cela dépendrait de variables non liées dans son corps, mais qui sont liées en dehors de ce dernier. –

1

Probablement open-bytevector-output-port est ce que je cherche:

#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) 

Résultat:

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