En informática, la serialización (ortografía de EE. UU.) O la serialización (ortografía del Reino Unido) es el proceso de traducir una estructura de datos o el estado de un objeto a un formato que se puede almacenar (por ejemplo, en un archivo o en un búfer de datos de memoria ) o transmitir (por ejemplo, a través de una red informática ) y reconstruido más tarde (posiblemente en un entorno informático diferente). [1] Cuando la serie de bits resultante se vuelve a leer de acuerdo con el formato de serialización, se puede utilizar para crear un clon semánticamente idéntico del objeto original. Para muchos objetos complejos, como aquellos que hacen un uso extensivo de referencias, este proceso no es sencillo. La serialización de objetos orientados a objetos no incluye ninguno de sus métodos asociados con los que estaban vinculados anteriormente.
Este proceso de serialización de un objeto también se denomina ordenación de un objeto en algunas situaciones. [2] [3] [4] La operación opuesta, extraer una estructura de datos de una serie de bytes, es deserialización (también llamada unserialización o unmarshalling ).
Métodos de:
Para que algunas de estas características sean útiles, se debe mantener la independencia de la arquitectura. Por ejemplo, para un uso máximo de la distribución, una computadora que se ejecute en una arquitectura de hardware diferente debería poder reconstruir de manera confiable un flujo de datos serializados, independientemente de su endianidad . Esto significa que el procedimiento más simple y rápido de copiar directamente el diseño de memoria de la estructura de datos no puede funcionar de manera confiable para todas las arquitecturas. Serializar la estructura de datos en un formato independiente de la arquitectura significa evitar los problemas de ordenamiento de bytes , diseño de memoria o simplemente diferentes formas de representar estructuras de datos en diferentes lenguajes de programación .
Inherente a cualquier esquema de serialización es que, debido a que la codificación de los datos es serial por definición, extraer una parte de la estructura de datos serializados requiere que todo el objeto sea leído de principio a fin y reconstruido. En muchas aplicaciones, esta linealidad es una ventaja, ya que permite utilizar interfaces de E / S comunes y simples para retener y transmitir el estado de un objeto. En aplicaciones donde un mayor rendimiento es un problema, puede tener sentido dedicar más esfuerzo a lidiar con una organización de almacenamiento no lineal más compleja.
Incluso en una sola máquina, los objetos punteros primitivos son demasiado frágiles para guardar porque los objetos a los que apuntan pueden volver a cargarse en una ubicación diferente en la memoria. Para hacer frente a esto, el proceso de serialización incluye un paso llamado desenrollar o desenchufar el puntero , donde las referencias directas del puntero se convierten en referencias basadas en el nombre o la posición. El proceso de deserialización incluye un paso inverso llamado puntero swizzling .
Dado que tanto la serialización como la deserialización se pueden controlar desde código común (por ejemplo, la función Serializar en Microsoft Foundation Classes ), es posible que el código común haga ambas cosas al mismo tiempo y, por lo tanto, 1) detecte diferencias entre los objetos que se están serializados y sus copias anteriores, y 2) proporcionar la entrada para la siguiente detección de este tipo. No es necesario construir la copia anterior porque las diferencias se pueden detectar sobre la marcha, una técnica llamada ejecución diferencial. Esto es útil en la programación de interfaces de usuario cuyo contenido varía en el tiempo: los objetos gráficos se pueden crear, eliminar, alterar o hacer para manejar eventos de entrada sin tener que escribir código por separado para hacer esas cosas.
La serialización rompe la opacidad de un tipo de datos abstracto al exponer potencialmente detalles de implementación privados. Las implementaciones triviales que serializan todos los miembros de datos pueden violar la encapsulación . [5]
Para disuadir a los competidores de fabricar productos compatibles, los editores de software propietario a menudo mantienen en secreto comercial los detalles de los formatos de serialización de sus programas . Algunos ocultan deliberadamente o incluso cifran los datos serializados. Sin embargo, la interoperabilidad requiere que las aplicaciones puedan comprender los formatos de serialización de las demás. Por lo tanto, las arquitecturas de llamadas a métodos remotos como CORBA definen sus formatos de serialización en detalle.
Muchas instituciones, como archivos y bibliotecas, intentan preparar sus archivos de respaldo para el futuro , en particular, los volcados de bases de datos , almacenándolos en algún formato serializado relativamente legible por humanos .
La tecnología Courier de Xerox Network Systems a principios de la década de 1980 influyó en el primer estándar ampliamente adoptado. Sun Microsystems publicó la Representación de datos externos (XDR) en 1987. [6] XDR es un formato abierto y estandarizado como STD 67 (RFC 4506).
A fines de la década de 1990, comenzó un impulso para proporcionar una alternativa a los protocolos de serialización estándar: XML , un subconjunto SGML , se utilizó para producir una codificación basada en texto legible por humanos . Tal codificación puede ser útil para objetos persistentes que pueden ser leídos y comprendidos por humanos, o comunicados a otros sistemas independientemente del lenguaje de programación. Tiene la desventaja de perder la codificación más compacta, basada en flujo de bytes, pero en este punto, las mayores capacidades de almacenamiento y transmisión hicieron que el tamaño del archivo fuera menos preocupante que en los primeros días de la informática. En la década de 2000, XML se usaba a menudo para la transferencia asincrónica de datos estructurados entre cliente y servidor en aplicaciones web Ajax . XML es un formato abierto y estandarizado comoRecomendación del W3C .
JSON , es una alternativa de texto plano más ligera a XML que también se usa comúnmente para la comunicación cliente-servidor en aplicaciones web. JSON se basa en la sintaxis de JavaScript , pero es independiente de JavaScript y también es compatible con otros lenguajes de programación. JSON es un formato abierto, estandarizado como STD 90 ( RFC 8259 ), ECMA-404 e ISO / IEC 21778: 2017 .
YAML , es un superconjunto JSON estricto e incluye características adicionales como una noción de etiquetado de tipos de datos, soporte para estructuras de datos no jerárquicas, la opción de estructurar datos con sangría y múltiples formas de citación de datos escalares. YAML es un formato abierto.
Las listas de propiedades se utilizan para la serialización mediante marcos de trabajo NeXTSTEP , GNUstep , macOS e iOS . Property list , o p-list para abreviar, no se refiere a un solo formato de serialización, sino a varias variantes diferentes, algunas legibles por humanos y una binaria.
Para conjuntos de datos científicos de gran volumen, como datos de satélite y salida de modelos numéricos climáticos, meteorológicos u oceánicos, se han desarrollado estándares de serialización binaria específicos, por ejemplo , HDF , netCDF y el antiguo GRIB .
Varios lenguajes de programación orientados a objetos admiten directamente la serialización de objetos (o el archivo de objetos ), ya sea mediante elementos sintácticos de azúcar o proporcionando una interfaz estándar para hacerlo. Los lenguajes que lo hacen incluyen Ruby , Smalltalk , Python , PHP , Objective-C , Delphi , Java y la familia de lenguajes .NET . También hay bibliotecas disponibles que agregan soporte de serialización a lenguajes que carecen de soporte nativo.
<cfwddx>
etiqueta y en JSON con la función SerializeJSON () .Read
clase de tipo define una función que extraerá los datos de la representación de cadena de los datos volcados. La Show
clase de tipo, a su vez, contiene elshow
función a partir de la cual se puede generar una representación de cadena del objeto. El programador no necesita definir las funciones explícitamente; simplemente declarar que un tipo deriva Read o Deriva Show, o ambos, puede hacer que el compilador genere las funciones apropiadas para muchos casos (pero no todos: los tipos de función, por ejemplo, no pueden derivar automáticamente Show o Leer). La instancia generada automáticamente para Show también produce código fuente válido, por lo que se puede generar el mismo valor de Haskell ejecutando el código producido por show en, por ejemplo, un intérprete de Haskell. [13] Para una serialización más eficiente, existen bibliotecas haskell que permiten la serialización de alta velocidad en formato binario, por ejemplo, binario .java.io.Serializable
interfaz . La implementación de la interfaz marca la clase como "aceptable para serializar", y Java luego maneja la serialización internamente. No hay métodos de serialización definidos en la Serializable
interfaz, pero una clase serializable puede opcionalmente definir métodos con ciertos nombres y firmas especiales que, si se definen, serán llamados como parte del proceso de serialización / deserialización. El lenguaje también permite al desarrollador anular el proceso de serialización más a fondo implementando otra interfaz, laExternalizable
interfaz, que incluye dos métodos especiales que se utilizan para guardar y restaurar el estado del objeto. Hay tres razones principales por las que los objetos no se pueden serializar de forma predeterminada y deben implementar la Serializable
interfaz para acceder al mecanismo de serialización de Java. En primer lugar, no todos los objetos capturan semánticas útiles en un estado serializado. Por ejemplo, un Thread
objeto está vinculado al estado de la JVM actual . No existe un contexto en el que un deserializadoThread
el objeto mantendría una semántica útil. En segundo lugar, el estado serializado de un objeto forma parte del contrato de compatibilidad de sus clases. Mantener la compatibilidad entre versiones de clases serializables requiere un esfuerzo y consideración adicionales. Por lo tanto, hacer que una clase sea serializable debe ser una decisión de diseño deliberada y no una condición predeterminada. Por último, la serialización permite el acceso a no transitoriosmiembros privados de una clase que no son accesibles de otra manera. Las clases que contienen información confidencial (por ejemplo, una contraseña) no deben ser serializables ni externalizables. El método de codificación estándar utiliza una traducción recursiva basada en gráficos del descriptor de clase del objeto y los campos serializables en un flujo de bytes. Los objetos primitivos, así como los objetos referenciados no estáticos y no transitorios, se codifican en la secuencia. Cada objeto al que hace referencia el objeto serializado a través de un campo que no está marcado comotransient
también debe ser serializado; y si algún objeto en el gráfico completo de referencias de objetos no transitorios no es serializable, la serialización fallará. El desarrollador puede influir en este comportamiento marcando objetos como transitorios o redefiniendo la serialización de un objeto para que una parte del gráfico de referencia se trunque y no se serialice. Java no usa el constructor para serializar objetos. Es posible serializar objetos Java a través de JDBC y almacenarlos en una base de datos. [14] Mientras se balanceaLos componentes implementan la interfaz serializable, no se garantiza que sean portátiles entre diferentes versiones de la máquina virtual Java. Como tal, un componente de Swing, o cualquier componente que lo herede, puede serializarse en un flujo de bytes, pero no se garantiza que este sea reconstituible en otra máquina.JSON
objeto integrado y sus métodos JSON.parse()
y JSON.stringify()
. Aunque JSON se basa originalmente en un subconjunto de JavaScript, [16] existen casos límite en los que JSON no es JavaScript válido. Específicamente, JSON permite que los terminadores de línea Unicode U + 2028 LINE SEPARATOR y U + 2029 PARAGRAPH SEPARATOR aparezcan sin escape en cadenas entre comillas, mientras que ECMAScript 2018 y versiones anteriores no. [17] [18] Consulte el artículo principal sobre JSON . serialize()
/ deserialize()
, [19] destinados a funcionar dentro de la misma versión de Julia, y / o instancia de la misma imagen del sistema. [20] El HDF5.jl
paquete ofrece una alternativa más estable, utilizando un formato documentado y una biblioteca común con envoltorios para diferentes idiomas, [21] mientras que se sugiere que el formato de serialización predeterminado se diseñó teniendo en cuenta el máximo rendimiento para la comunicación de red. [22]read
" y " print
". Una variable foo que contenga, por ejemplo, una lista de matrices se imprimirá mediante (print foo)
. De manera similar, un objeto se puede leer de una secuencia denominada s por (read s)
. Estas dos partes de la implementación Lisp se denominan Impresora y Lector. La salida de " print
" es legible por humanos; que utiliza listas delimitadas por paréntesis, por ejemplo: (4 2.9 "x" y)
. En muchos tipos de Lisp, incluido Common Lisp , la impresora no puede representar todos los tipos de datos porque no está claro cómo hacerlo. En Common Lisp, por ejemplo, la impresora no puede imprimir objetos CLOS. En cambio, el programador puede escribir un método en la función genéricaprint-object
, esto se invocará cuando se imprima el objeto. Esto es algo similar al método utilizado en Ruby. El código Lisp en sí está escrito en la sintaxis del lector, llamada sintaxis de lectura. La mayoría de los lenguajes usan analizadores distintos y separados para manejar código y datos, Lisp solo usa uno. Un archivo que contiene código lisp puede leerse en la memoria como una estructura de datos, transformarse por otro programa y luego posiblemente ejecutarse o escribirse, como en un ciclo de lectura-evaluación-impresión . No todos los lectores / escritores admiten estructuras cíclicas, recursivas o compartidas.Marshal
módulo [3] y las funciones de Pervasives output_value
y input_value
. Si bien la programación OCaml se verifica de forma estática, los usos de laMarshal
El módulo puede romper las garantías de tipo, ya que no hay forma de verificar si una secuencia no ordenada representa objetos del tipo esperado. En OCaml es difícil ordenar una función o una estructura de datos que contiene una función (por ejemplo, un objeto que contiene un método), porque el código ejecutable en funciones no se puede transmitir a través de diferentes programas. (Hay una bandera para ordenar la posición del código de una función, pero solo se puede deshacer exactamente en el mismo programa). Las funciones de clasificación estándar pueden preservar el uso compartido y el manejo de datos cíclicos, que se pueden configurar mediante una bandera.Storable
, JSON::XS
y FreezeThaw
. Storable incluye funciones para serializar y deserializar estructuras de datos Perl hacia y desde archivos o escalares Perl. Además de serializar directamente en archivos, Storable
incluye la freeze
función para devolver una copia serializada de los datos empaquetados en un escalar y thaw
deserializar dicho escalar. Esto es útil para enviar una estructura de datos compleja a través de un socket de red o almacenarla en una base de datos. Al serializar estructuras con Storable
, existen funciones seguras de red que siempre almacenan sus datos en un formato que es legible en cualquier computadora a un pequeño costo de velocidad. Estas funciones se nombran nstore
,nfreeze
, etc. No hay funciones "n" para deserializar estas estructuras - las estructuras regular thaw
y retrieve
deserializar serializadas con las n
funciones " " y sus equivalentes específicos de la máquina.serialize()
y unserialize()
. [25] PHP puede serializar cualquiera de sus tipos de datos excepto los recursos (punteros de archivo, sockets, etc.). La unserialize()
función incorporada a menudo es peligrosa cuando se usa con datos que no son de confianza. [26] Para los objetos, hay dos " métodos mágicos " que se pueden implementar dentro de una clase - __sleep()
y __wakeup()
- que se llaman desde dentro serialize()
yunserialize()
, respectivamente, que pueden limpiar y restaurar un objeto. Por ejemplo, puede ser conveniente cerrar una conexión de base de datos en la serialización y restaurar la conexión en la deserialización; esta funcionalidad se manejaría en estos dos métodos mágicos. También permiten que el objeto elija qué propiedades se serializan. Desde PHP 5.1, existe un mecanismo de serialización orientado a objetos para objetos, la Serializable
interfaz. [27]write_term/3
y serializar a través de los predicados integrados read/1
y read_term/2
. La secuencia resultante es texto sin comprimir (en alguna codificación determinada por la configuración de la secuencia de destino), con cualquier variable libre en el término representada por nombres de variable de marcador de posición. El predicado write_term/3
está estandarizado en la Especificación ISO para Prolog(ISO / IEC 13211-1) en las páginas 59 y siguientes. ("Escribir un término, § 7.10.5"). Por lo tanto, se espera que los términos serializados por una implementación puedan ser serializados por otra sin ambigüedad ni sorpresas. En la práctica, las extensiones específicas de la implementación (por ejemplo, los diccionarios de SWI-Prolog) pueden usar estructuras de términos no estándar, por lo que la interoperabilidad puede romperse en casos extremos. Como ejemplos, consulte las páginas de manual correspondientes para SWI-Prolog, [28] SICStus Prolog, [29] GNU Prolog. [30] Se deja al implementador si los términos serializados recibidos a través de la red y cómo se comparan con una especificación (después de que haya ocurrido la deserialización del flujo de caracteres). Las gramáticas de cláusulas definidas integradas de Prolog se pueden aplicar en esa etapa.pickle
biblioteca estándar , en alusión al término decapado [31] [32] [33] de los sistemas de bases de datos para describir la serialización de datos ( deshabilitación para deserialización ). Pickle utiliza una máquina virtual simple basada en pilas que registra las instrucciones utilizadas para reconstruir el objeto. Es un formato de serialización de versiones cruzadas personalizable pero inseguro (no seguro contra datos erróneos o maliciosos). Los datos mal formados o construidos maliciosamente pueden hacer que el deserializador importe módulos arbitrarios y cree una instancia de cualquier objeto. [34] [35]La biblioteca estándar también incluye módulos que serializan a formatos de datos estándar: json
(con soporte incorporado para tipos de colección y escalares básicos y capaz de admitir tipos arbitrarios a través de ganchos de codificación y decodificación ). plistlib
(con soporte para formatos de lista de propiedades binarios y XML ). xdrlib
(con soporte para el estándar de Representación de datos externos (XDR) como se describe en RFC 1014). Finalmente, se recomienda que un objeto __repr__
sea evaluable en el entorno adecuado, lo que lo convierte en una coincidencia aproximada para Common Lisp print-object
. No todos los tipos de objetos se pueden eliminar automáticamente, especialmente los que contienen recursos del sistema operativo, como identificadores de archivos., pero los usuarios pueden registrar funciones personalizadas de "reducción" y construcción para admitir el decapado y despegado de tipos arbitrarios. Pickle se implementó originalmente como el pickle
módulo Python puro , pero, en las versiones de Python anteriores a la 3.0, el cPickle
módulo (también integrado) ofrece un rendimiento mejorado (hasta 1000 veces más rápido [34] ). El cPickle
fue adaptado del proyecto Unladen Swallow . En Python 3, los usuarios siempre deben importar la versión estándar, que intenta importar la versión acelerada y recurre a la versión pura de Python. [36]dput
que escribe una representación de texto ASCII de un objeto R en un archivo o conexión. Una representación se puede leer de un archivo usando dget
. [37] Más específico, la función serialize
serializa un objeto R a una conexión, siendo la salida un vector sin formato codificado en formato hexadecimal. La unserialize
función permite leer un objeto desde una conexión o un vector sin formato. [38]save/all
) o en un string!
( mold/all
). Las cadenas y los archivos se pueden deserializar mediante la función polimórfica load
. RProtoBuf
proporciona serialización de datos en varios idiomas en R, utilizando Protocol Buffers . [39]Marshal
con 2 métodos dump
y load
, similar a las utilidades estándar de Unix dump
y restore
. Estos métodos se serializan en la clase estándar String
, es decir, se convierten efectivamente en una secuencia de bytes. Algunos objetos no se pueden serializar (hacerlo generaría una TypeError
excepción): enlaces, objetos de procedimiento, instancias de clase IO, objetos singleton e interfaces. Si una clase requiere una serialización personalizada (por ejemplo, requiere que se realicen ciertas acciones de limpieza en el volcado / restauración), se puede realizar implementando 2 métodos: _dump
y _load
. El método de instancia _dump
debe devolver unString
objeto que contiene toda la información necesaria para reconstituir los objetos de esta clase y todos los objetos referenciados hasta una profundidad máxima dada como un parámetro entero (un valor de -1 implica que la verificación de profundidad debe estar deshabilitada). El método de clase _load
debe tomar ay String
devolver un objeto de esta clase.storeOn:
/ readFrom:
. El storeOn:
método genera el texto de una expresión de Smalltalk que, cuando se evalúa utilizandoreadFrom:
- recrea el objeto original. Este esquema es especial, ya que utiliza una descripción de procedimiento del objeto, no los datos en sí. Por lo tanto, es muy flexible, lo que permite que las clases definan representaciones más compactas. Sin embargo, en su forma original, no maneja estructuras de datos cíclicas ni preserva la identidad de las referencias compartidas (es decir, dos referencias de un solo objeto se restaurarán como referencias a dos copias iguales, pero no idénticas). Para ello, existen diversas alternativas portátiles y no portátiles. Algunos de ellos son específicos de una implementación de Smalltalk o biblioteca de clases en particular. Hay varias formas en Squeak Smalltalk de serializar y almacenar objetos. Los storeOn:/readFrom:
formatos de almacenamiento binarios más fáciles y usados son y basados enSmartRefStream
serializadores. Además, los objetos empaquetados se pueden almacenar y recuperar utilizandoImageSegments
. Ambos proporcionan el denominado "marco de almacenamiento de objetos binarios", que admite la serialización y la recuperación desde un formato binario compacto. Ambos manejan estructuras cíclicas, recursivas y compartidas, almacenamiento / recuperación de información de clase y metaclase e incluyen mecanismos para la migración de objetos "sobre la marcha" (es decir, para convertir instancias que fueron escritas por una versión anterior de una clase con un diseño de objeto diferente). Las API son similares (storeBinary / readBinary), pero los detalles de codificación son diferentes, lo que hace que estos dos formatos sean incompatibles. Sin embargo, el código Smalltalk / X es de código abierto y gratuito y se puede cargar en otros Smalltalks para permitir el intercambio de objetos entre dialectos. La serialización de objetos no forma parte de la especificación ANSI Smalltalk. Como resultado, el código para serializar un objeto varía según la implementación de Smalltalk.Los datos binarios resultantes también varían. Por ejemplo, un objeto serializado creado en Squeak Smalltalk no se puede restaurar enAmbrai Smalltalk . En consecuencia, varias aplicaciones que funcionan en múltiples implementaciones de Smalltalk que dependen de la serialización de objetos no pueden compartir datos entre estas diferentes implementaciones. Estas aplicaciones incluyen la base de datos de objetos MinneStore [40] y algunos paquetes RPC . Una solución a este problema es SIXX "Novedades" . SIXX: intercambio de instancias de Smalltalk en XML . 23 de enero de 2010 . Consultado el 25 de julio de 2021 .</ref>, que es un paquete para múltiples Smalltalks que usa un formato basado en XML para la serialización.Encodable
y Decodable
(compuestos juntos como Codable
), que permiten serializar o deserializar instancias de tipos conformes a JSON , listas de propiedades u otros formatos. [41] El compilador puede generar implementaciones predeterminadas de estos protocolos para tipos cuyas propiedades almacenadas también son Decodable
o Encodable
.Export-CliXML
. Export-CliXML
serializa objetos .NET y almacena el XML resultante en un archivo. Para reconstituir los objetos, use el Import-CliXML
cmdlet, que genera un objeto deserializado a partir del XML en el archivo exportado. Los objetos deserializados, a menudo conocidos como "bolsas de propiedades", no son objetos vivos; son instantáneas que tienen propiedades, pero no métodos. Las estructuras de datos bidimensionales también se pueden (des) serializar en formato CSV utilizando los cmdlets integrados Import-CSV
y Export-CSV
.Le permite tomar un objeto o grupo de objetos, ponerlos en un disco o enviarlos a través de un mecanismo de transporte por cable o inalámbrico, luego, más tarde, tal vez en otra computadora, revertir el proceso, resucitando los objetos originales.
Los mecanismos básicos son aplanar el (los) objeto (s) en un flujo unidimensional de bits y convertir ese flujo de bits nuevamente en el (los) objeto (s) original (es).
La serialización, que se explica a continuación, es un ejemplo de una herramienta que pueden utilizar los objetos dentro de un sistema de objetos para operar en el gráfico en el que están incrustados. Esto parece requerir violar la encapsulación proporcionada por el modelo de objetos puro.
Hay muchos tipos de serializadores;
producen datos muy compactos muy rápido.
Hay serializadores para mensajería, para almacenes de datos, para ordenar objetos.
¿Cuál es el mejor serializador en .NET?
Nuestra implementación hace uso de un mecanismo llamado "pickles", que convertirá entre cualquier estructura de datos fuertemente tipada y una representación de esa estructura adecuada para almacenar en archivos de disco permanente. La operación Pickle.Write toma un puntero a una estructura de datos fuertemente tipada y entrega búferes de bits para escribir en el disco. Por el contrario, Pickle.Read lee búferes de bits del disco y entrega una copia de la estructura de datos original. (*) Esta conversión implica identificar las ocurrencias de direcciones en la estructura y disponer que cuando la estructura se lea desde el disco, las direcciones sean reemplazado con direcciones válidas en el entorno de ejecución actual. El mecanismo de pickle es completamente automático: es impulsado por las estructuras de escritura en tiempo de ejecución que están presentes para nuestro mecanismo de recolección de basura. ...(*) El decapado es bastante similar al concepto de clasificación en llamadas a procedimientos remotos. Pero, de hecho, nuestra implementación de decapado funciona solo al interpretar en tiempo de ejecución la estructura de valores tipados dinámicamente, mientras que nuestra implementación RPC funciona solo generando código para la clasificación de valores tipados estáticamente. Cada instalación se beneficiaría de agregar los mecanismos de la otra, pero eso aún no se ha hecho.
Origen del nombre 'aplanamiento': como quiero dejar el módulo original 'marshal' solo, y Jim se quejó de que 'serialización' también significa algo totalmente diferente que es realmente relevante en el contexto del acceso concurrente a objetos persistentes, usaré el término "aplanamiento" de ahora en adelante. ... (El sistema Modula-3 usa el término datos 'encurtidos' para este concepto. Probablemente ya hayan resuelto todos los problemas,y de una manera segura de escribir :-)