В вычислительной технике сериализация (или сериализация ) — это процесс перевода структуры данных или состояния объекта в формат, который может быть сохранен (например, файлы на вторичных устройствах хранения , буферы данных на первичных устройствах хранения) или передан (например, потоки данных по компьютерным сетям ) и восстановлен позже (возможно, в другой компьютерной среде). [1] Когда полученная последовательность битов перечитывается в соответствии с форматом сериализации, ее можно использовать для создания семантически идентичного клона исходного объекта. Для многих сложных объектов, например, тех, которые широко используют ссылки , этот процесс не является простым. Сериализация объектов не включает ни один из их связанных методов , с которыми они были ранее связаны.
Этот процесс сериализации объекта в некоторых ситуациях также называется маршаллингом объекта. [2] [3] [4] Противоположная операция, извлечение структуры данных из последовательности байтов, называется десериализацией (также называемой десериализацией или демаршаллингом ).
В сетевом оборудовании часть, отвечающая за сериализацию и десериализацию, обычно называется SerDes .
Использование сериализации включает в себя:
Чтобы некоторые из этих функций были полезными, необходимо поддерживать независимость от архитектуры. Например, для максимального использования распределения компьютер, работающий на другой аппаратной архитектуре, должен иметь возможность надежно реконструировать сериализованный поток данных независимо от порядка байтов . Это означает, что более простая и быстрая процедура прямого копирования структуры памяти структуры данных не может работать надежно для всех архитектур. Сериализация структуры данных в архитектурно-независимом формате означает предотвращение проблем с порядком байтов , структурой памяти или просто разными способами представления структур данных в разных языках программирования .
Любой схеме сериализации присуще то, что, поскольку кодирование данных по определению последовательно, извлечение одной части структуры сериализованных данных требует, чтобы весь объект был прочитан от начала до конца и реконструирован. Во многих приложениях эта линейность является преимуществом, поскольку она позволяет использовать простые, общие интерфейсы ввода-вывода для хранения и передачи состояния объекта. В приложениях, где важна более высокая производительность, может иметь смысл приложить больше усилий для работы с более сложной, нелинейной организацией хранения.
Даже на одной машине примитивные объекты указателей слишком хрупки для сохранения, поскольку объекты, на которые они указывают, могут быть перезагружены в другое место в памяти. Чтобы справиться с этим, процесс сериализации включает шаг, называемый unswizzling или pointer unswizzling , где прямые ссылки указателя преобразуются в ссылки на основе имени или положения. Процесс десериализации включает обратный шаг, называемый pointer swizzling .
Поскольку и сериализация, и десериализация могут управляться из общего кода (например, функция Serialize в Microsoft Foundation Classes ), общий код может делать и то, и другое одновременно, и, таким образом, 1) обнаруживать различия между сериализуемыми объектами и их предыдущими копиями, и 2) предоставлять входные данные для следующего такого обнаружения. Фактически нет необходимости создавать предыдущую копию, поскольку различия могут быть обнаружены на лету, метод, называемый дифференциальным выполнением. Это полезно при программировании пользовательских интерфейсов, содержимое которых изменяется во времени — графические объекты можно создавать, удалять, изменять или заставлять их обрабатывать события ввода без необходимости писать отдельный код для выполнения этих действий.
Сериализация нарушает непрозрачность абстрактного типа данных , потенциально раскрывая частные детали реализации. Тривиальные реализации, которые сериализуют все элементы данных, могут нарушать инкапсуляцию . [5]
Чтобы отговорить конкурентов от создания совместимых продуктов, издатели проприетарного программного обеспечения часто держат подробности форматов сериализации своих программ в коммерческой тайне . Некоторые намеренно скрывают или даже шифруют сериализованные данные. Тем не менее, для обеспечения взаимодействия необходимо, чтобы приложения могли понимать форматы сериализации друг друга. Поэтому архитектуры удаленного вызова методов, такие как CORBA, подробно определяют свои форматы сериализации.
Многие учреждения, такие как архивы и библиотеки, пытаются защитить свои резервные копии данных (в частности, дампы баз данных ) от непредвиденных расходов в будущем , сохраняя их в каком-либо относительно понятном для человека сериализованном формате.
Технология Xerox Network Systems Courier в начале 1980-х годов повлияла на первый широко принятый стандарт. Sun Microsystems опубликовала External Data Representation (XDR) в 1987 году. [6] XDR — открытый формат , стандартизированный как STD 67 (RFC 4506).
В конце 1990-х годов началась попытка предоставить альтернативу стандартным протоколам сериализации: XML , подмножество SGML , использовалось для создания текстовой кодировки, читаемой человеком . Такая кодировка может быть полезна для постоянных объектов, которые могут быть прочитаны и поняты людьми или переданы в другие системы независимо от языка программирования. Недостатком является потеря более компактной кодировки на основе байтового потока, но к этому моменту большие возможности хранения и передачи сделали размер файла менее важным, чем в ранние дни вычислений. В 2000-х годах XML часто использовался для асинхронной передачи структурированных данных между клиентом и сервером в веб-приложениях Ajax . XML является открытым форматом и стандартизирован как рекомендация W3C.
JSON — это легкая альтернатива XML в виде простого текста, которая также широко используется для клиент-серверной коммуникации в веб-приложениях. JSON основан на синтаксисе JavaScript , но независим от JavaScript и поддерживается во многих других языках программирования. JSON — это открытый формат, стандартизированный как STD 90 ( RFC 8259), ECMA-404 и ISO/IEC 21778:2017.
YAML — это строгое расширение JSON, включающее дополнительные функции, такие как теги типов данных, поддержка циклических структур данных, чувствительный к отступам синтаксис и несколько форм цитирования скалярных данных. YAML — открытый формат.
Списки свойств используются для сериализации фреймворками NeXTSTEP , GNUstep , macOS и iOS . Список свойств , или p-list для краткости, не относится к одному формату сериализации, а вместо этого к нескольким различным вариантам, некоторые из которых понятны человеку, а один — двоичный.
Для больших объемов научных данных, таких как спутниковые данные и выходные данные численных моделей климата, погоды или океана, были разработаны специальные стандарты бинарной сериализации, например HDF , netCDF и более старый GRIB .
Несколько объектно-ориентированных языков программирования напрямую поддерживают сериализацию объектов (или архивацию объектов ), либо с помощью синтаксических сахарных элементов, либо предоставляя стандартный интерфейс для этого. Языки, которые это делают, включают Ruby , Smalltalk , Python , PHP , Objective-C , Delphi , Java и семейство языков .NET . Также доступны библиотеки, которые добавляют поддержку сериализации в языки, в которых отсутствует ее собственная поддержка.
C и C++ не предоставляют сериализацию как какую-либо высокоуровневую конструкцию, но оба языка поддерживают запись любых встроенных типов данных , а также простых старых структур данных в качестве двоичных данных. Таким образом, обычно тривиально писать пользовательские функции сериализации. Более того, решения на основе компилятора, такие как система ODB ORM для C++ и набор инструментов gSOAP для C и C++, способны автоматически создавать код сериализации с небольшими изменениями или без них в объявлениях классов. Другими популярными фреймворками сериализации являются Boost.Serialization [7] из Boost Framework , фреймворк S11n [8] и Cereal. [9] Фреймворк MFC (Microsoft) также предоставляет методологию сериализации как часть своей архитектуры Document-View.
CFML позволяет сериализовать структуры данных в WDDX с помощью <cfwddx>
тега и в JSON с помощью функции SerializeJSON().
Delphi предоставляет встроенный механизм для сериализации компонентов (также называемых постоянными объектами), который полностью интегрирован с его IDE . Содержимое компонента сохраняется в файле DFM и перезагружается на лету.
Go изначально поддерживает демаршаллинг/маршаллинг данных JSON и XML . [10] Также существуют сторонние модули, которые поддерживают YAML [11] и Protocol Buffers . [12] Go также поддерживает Gobs . [13]
В Haskell сериализация поддерживается для типов, которые являются членами классов типов Read и Show . Каждый тип, который является членом Read
класса типов, определяет функцию, которая извлечет данные из строкового представления выгруженных данных. Show
Класс типов, в свою очередь, содержит show
функцию, из которой может быть сгенерировано строковое представление объекта. Программисту не нужно явно определять функции — простое объявление типа как производного от Read или Show, или и того, и другого, может заставить компилятор сгенерировать соответствующие функции для многих случаев (но не для всех: например, типы функций не могут автоматически выводить Show или Read). Автоматически сгенерированный экземпляр для Show также создает допустимый исходный код, поэтому то же значение Haskell может быть сгенерировано путем запуска кода, созданного show, например, в интерпретаторе Haskell. [14] Для более эффективной сериализации существуют библиотеки haskell, которые позволяют выполнять высокоскоростную сериализацию в двоичном формате, например, binary.
Java обеспечивает автоматическую сериализацию, которая требует, чтобы объект был помечен путем реализации java.io.Serializable
интерфейса . Реализация интерфейса помечает класс как «подходящий для сериализации», и затем Java обрабатывает сериализацию внутренне. В интерфейсе не определены методы сериализации Serializable
, но сериализуемый класс может опционально определять методы с определенными специальными именами и сигнатурами, которые, если определены, будут вызываться как часть процесса сериализации/десериализации. Язык также позволяет разработчику более тщательно переопределять процесс сериализации, реализуя другой интерфейс, Externalizable
интерфейс, который включает два специальных метода, используемых для сохранения и восстановления состояния объекта.
Существует три основные причины, по которым объекты не сериализуемы по умолчанию и должны реализовывать Serializable
интерфейс для доступа к механизму сериализации Java.
Во-первых, не все объекты захватывают полезную семантику в сериализованном состоянии. Например, объект Thread
привязан к состоянию текущей JVM . Не существует контекста, в котором десериализованный Thread
объект поддерживал бы полезную семантику.
Во-вторых, сериализованное состояние объекта является частью контракта совместимости его класса. Поддержание совместимости между версиями сериализуемых классов требует дополнительных усилий и рассмотрения. Поэтому создание сериализуемого класса должно быть преднамеренным проектным решением, а не условием по умолчанию.
Наконец, сериализация позволяет получить доступ к непереходным закрытым членам класса, которые в противном случае недоступны. Классы, содержащие конфиденциальную информацию (например, пароль), не должны быть сериализуемыми или экстернализуемыми. [15] : 339–345 Стандартный метод кодирования использует рекурсивный графовый перевод дескриптора класса объекта и сериализуемых полей в поток байтов. Примитивы , а также непереходные, нестатические ссылочные объекты кодируются в поток. Каждый объект, на который ссылается сериализуемый объект через поле, не помеченное как , transient
также должен быть сериализован; и если какой-либо объект в полном графе непереходных ссылок на объекты не является сериализуемым, то сериализация завершится неудачей. Разработчик может влиять на это поведение, отмечая объекты как переходные или переопределяя сериализацию для объекта так, чтобы некоторая часть ссылочного графа была усечена и не сериализовалась.
Java не использует конструктор для сериализации объектов. Можно сериализовать объекты Java через JDBC и сохранять их в базе данных. [16] В то время как Swingкомпоненты реализуют интерфейс Serializable, они не гарантированно будут переносимы между различными версиями виртуальной машины Java. Таким образом, компонент Swing или любой компонент, который его наследует, может быть сериализован в поток байтов, но не гарантируется, что это будет воспроизводимо на другой машине.
Начиная с ECMAScript 5.1, [17] JavaScript включает встроенный JSON
объект и его методы JSON.parse()
и JSON.stringify()
. Хотя JSON изначально основан на подмножестве JavaScript, [18] существуют граничные случаи, когда JSON не является допустимым JavaScript. В частности, JSON позволяет символам конца строки Unicode U+2028 LINE SEPARATOR и U+2029 PARAGRAPH SEPARATOR появляться неэкранированными в строках в кавычках, тогда как ECMAScript 2018 и более ранние версии этого не делают. [19] [20] См. основную статью о JSON [ сломанный якорь ] .
Julia реализует сериализацию через модули serialize()
/ deserialize()
, [21] предназначенные для работы в пределах одной версии Julia и/или экземпляра одного и того же образа системы. [22] Пакет HDF5.jl
предлагает более стабильную альтернативу, используя документированный формат и общую библиотеку с оболочками для разных языков, [23] в то время как формат сериализации по умолчанию, как предполагается, был разработан скорее с учетом максимальной производительности для сетевой коммуникации. [24]
Обычно структура данных Lisp может быть сериализована с помощью функций " read
" и " print
". Переменная foo, содержащая, например, список массивов, будет напечатана функцией (print foo)
. Аналогично объект может быть прочитан из потока с именем s функцией (read s)
. Эти две части реализации Lisp называются Printer и Reader. Вывод " print
" удобочитаем; он использует списки, разграниченные круглыми скобками, например: . Во многих типах Lisp, включая Common Lisp , принтер не может представлять все типы данных, поскольку неясно, как это сделать. Например, в Common Lisp принтер не может печатать объекты CLOS. Вместо этого программист может написать метод для универсальной функции , он будет вызван при печати объекта. Это несколько похоже на метод, используемый в Ruby. Сам код Lisp написан в синтаксисе читателя, называемом синтаксисом чтения. Большинство языков используют отдельные и разные парсеры для работы с кодом и данными, Lisp использует только один. Файл, содержащий код LISP, может быть прочитан в память как структура данных, преобразован другой программой, затем, возможно, выполнен или записан, например, в цикле чтение-вычисление-печать . Не все считыватели/писатели поддерживают циклические, рекурсивные или общие структуры.(4 2.9 "x" y)
print-object
.NET имеет несколько сериализаторов, разработанных Microsoft . Также есть много сериализаторов от третьих лиц. Более дюжины сериализаторов обсуждаются и тестируются здесь. [25] и здесь [26]
Стандартная библиотека OCamlMarshal
обеспечивает маршалинг через модуль [3] и функции Pervasives output_value
и input_value
. Хотя программирование OCaml статически проверяется на соответствие типам, использование модуля Marshal
может нарушить гарантии типов, поскольку нет способа проверить, представляет ли немаршализированный поток объекты ожидаемого типа. В OCaml сложно маршалировать функцию или структуру данных, содержащую функцию (например, объект, содержащий метод), поскольку исполняемый код в функциях не может передаваться между разными программами. (Существует флаг для маршалинга позиции кода функции, но он может быть демаршаллирован только в той же программе). Стандартные функции маршалинга могут сохранять совместное использование и обрабатывать циклические данные, которые можно настроить с помощью флага.
Несколько модулей Perl , доступных на CPAN, предоставляют механизмы сериализации, включая Storable
, JSON::XS
и FreezeThaw
. Storable включает функции для сериализации и десериализации структур данных Perl в файлы или скаляры Perl и из них. В дополнение к сериализации непосредственно в файлы, Storable
включает freeze
функцию возврата сериализованной копии данных, упакованных в скаляр, и thaw
десериализации такого скаляра. Это полезно для отправки сложной структуры данных по сетевому сокету или сохранения ее в базе данных. При сериализации структур с помощью Storable
существуют сетевые безопасные функции, которые всегда сохраняют свои данные в формате, читаемом на любом компьютере, с небольшой потерей скорости. Эти функции называются nstore
, nfreeze
и т. д. Нет функций "n" для десериализации этих структур — обычные thaw
и retrieve
deserialize структуры, сериализованные с помощью n
функций " " и их машинно-специфичных эквивалентов.
PHP изначально реализовал сериализацию через встроенные функции serialize()
и unserialize()
. [27] PHP может сериализовать любые типы данных, кроме ресурсов (указатели файлов, сокеты и т. д.). Встроенная unserialize()
функция часто опасна, когда используется с полностью ненадежными данными. [28] Для объектов есть два « магических метода», которые могут быть реализованы внутри класса — __sleep()
и __wakeup()
— которые вызываются из serialize()
и unserialize()
, соответственно, которые могут очищать и восстанавливать объект. Например, может быть желательно закрыть соединение с базой данных при сериализации и восстановить соединение при десериализации; эта функциональность будет обрабатываться в этих двух магических методах. Они также позволяют объекту выбирать, какие свойства сериализуются. Начиная с PHP 5.1, существует объектно-ориентированный механизм сериализации для объектов, интерфейс Serializable
. [29]
Структура термина Prolog , которая является единственной структурой данных языка, может быть сериализована наружу через встроенный предикат write_term/3
и сериализована внутрь через встроенные предикаты read/1
и read_term/2
. Результирующий поток представляет собой несжатый текст (в некоторой кодировке, определяемой конфигурацией целевого потока), при этом любые свободные переменные в термине представлены именами переменных-заполнителей. Предикат write_term/3
стандартизирован в спецификации ISO для Prolog (ISO/IEC 13211-1) на страницах 59 и далее. («Написание термина, § 7.10.5»). Поэтому ожидается, что термины, сериализованные наружу одной реализацией, могут быть сериализованы внутрь другой без неоднозначности или неожиданностей. На практике расширения, зависящие от реализации (например, словари SWI-Prolog), могут использовать нестандартные структуры терминов, поэтому взаимодействие может нарушаться в крайних случаях. В качестве примеров см. соответствующие страницы руководства для SWI-Prolog, [30] SICStus Prolog, [31] GNU Prolog. [32] Вопрос о том, будут ли и как сериализованные термины, полученные по сети, проверяться на соответствие спецификации (после десериализации из потока символов), остается на усмотрение разработчика. На этом этапе можно применять встроенные в Prolog грамматики определенных предложений .
Основной механизм сериализации — это pickle
стандартный модуль библиотеки , ссылающийся на термин систем баз данных pickling [33] [34] [35] для описания сериализации данных ( unpickling для десериализации ). Pickle использует простую виртуальную машину на основе стека , которая записывает инструкции, используемые для реконструкции объекта. Это настраиваемый кросс-версионный, но небезопасный (не защищенный от ошибочных или вредоносных данных) формат сериализации. Неправильно сформированные или вредоносно созданные данные могут привести к тому, что десериализатор импортирует произвольные модули и создает экземпляр любого объекта. [36] [37] Стандартная библиотека также включает модули, сериализующиеся в стандартные форматы данных: (со встроенной поддержкой базовых скалярных и коллекционных типов и способные поддерживать произвольные типы с помощью хуков кодирования и декодирования). (с поддержкой как двоичных, так и XML- форматов списка свойств ). (с поддержкой стандарта внешнего представления данных (XDR), как описано в RFC 1014). Наконец, рекомендуется, чтобы объект можно было оценить в правильной среде, что делает его грубым соответствием Common Lisp . Не все типы объектов могут быть замаринованы автоматически, особенно те, которые содержат ресурсы операционной системы , такие как дескрипторы файлов , но пользователи могут регистрировать пользовательские функции «сокращения» и построения для поддержки замаринования и расмаринования произвольных типов. Pickle изначально был реализован как чистый модуль Python , но в версиях Python до 3.0 этот модуль (также встроенный) обеспечивает улучшенную производительность (до 1000 раз быстрее [36] ). Он был адаптирован из проекта Unladen Swallow . В Python 3 пользователи всегда должны импортировать стандартную версию, которая пытается импортировать ускоренную версию и возвращается к чистой версии Python. [38]json
plistlib
xdrlib
__repr__
print-object
pickle
cPickle
cPickle
R имеет функцию dput
, которая записывает текстовое представление ASCII объекта R в файл или соединение. Представление может быть прочитано из файла с помощью dget
. [39] Более конкретно, функция serialize
сериализует объект R в соединение, выводя необработанный вектор, закодированный в шестнадцатеричном формате. Функция unserialize
позволяет считывать объект из соединения или необработанного вектора. [40]
REBOL будет сериализовать в файл ( save/all
) или в string!
( mold/all
). Строки и файлы могут быть десериализованы с помощью полиморфной load
функции. RProtoBuf
обеспечивает кросс-языковую сериализацию данных в R, используя Protocol Buffers . [41]
Ruby включает стандартный модуль Marshal
с 2 методами dump
и load
, родственными стандартным утилитам Unix dump
и restore
. Эти методы сериализуются в стандартный класс String
, то есть они фактически становятся последовательностью байтов. Некоторые объекты не могут быть сериализованы (это вызовет TypeError
исключение): привязки, объекты процедур, экземпляры класса IO, объекты-одиночки и интерфейсы. Если класс требует пользовательской сериализации (например, он требует определенных действий по очистке, выполняемых при дампе / восстановлении), это можно сделать, реализовав 2 метода: _dump
и _load
. Метод экземпляра _dump
должен возвращать String
объект, содержащий всю информацию, необходимую для воссоздания объектов этого класса и всех ссылочных объектов до максимальной глубины, заданной как целочисленный параметр (значение -1 подразумевает, что проверка глубины должна быть отключена). Метод класса _load
должен принимать String
и возвращать объект этого класса.
Serde
— наиболее широко используемая библиотека или крейт для сериализации в Rust .
В общем случае нерекурсивные и неразделяемые объекты можно сохранять и извлекать в удобочитаемой форме с помощью протокола storeOn:
/ readFrom:
. storeOn:
Метод генерирует текст выражения Smalltalk, которое при оценке с помощью readFrom:
воссоздает исходный объект. Эта схема особенная, поскольку использует процедурное описание объекта, а не сами данные. Поэтому она очень гибкая, что позволяет классам определять более компактные представления. Однако в своей исходной форме она не обрабатывает циклические структуры данных и не сохраняет идентичность разделяемых ссылок (т. е. две ссылки на один объект будут восстановлены как ссылки на две равные, но не идентичные копии). Для этого существуют различные переносимые и непереносимые альтернативы. Некоторые из них специфичны для конкретной реализации Smalltalk или библиотеки классов. В Squeak Smalltalk есть несколько способов сериализации и хранения объектов. Самыми простыми и наиболее используемыми являются storeOn:/readFrom:
и двоичные форматы хранения, основанные на SmartRefStream
сериализаторах. Кроме того, связанные объекты можно сохранять и извлекать с помощью ImageSegments
. Оба предоставляют так называемую «структуру хранения двоичных объектов», которая поддерживает сериализацию в компактную двоичную форму и извлечение из нее. Оба обрабатывают циклические, рекурсивные и общие структуры, хранение/извлечение информации о классах и метаклассах и включают механизмы для миграции объектов «на лету» (т. е. для преобразования экземпляров, которые были написаны старой версией класса с другой компоновкой объектов). API похожи (storeBinary/readBinary), но детали кодирования различаются, что делает эти два формата несовместимыми. Однако код Smalltalk/X является открытым исходным кодом и бесплатным и может быть загружен в другие Smalltalk для обеспечения кросс-диалектного обмена объектами. Сериализация объектов не является частью спецификации ANSI Smalltalk. В результате код для сериализации объекта различается в зависимости от реализации Smalltalk. Результирующие двоичные данные также различаются. Например, сериализованный объект, созданный в Squeak Smalltalk, не может быть восстановлен в Ambrai Smalltalk. Следовательно, различные приложения, которые работают на нескольких реализациях Smalltalk, которые полагаются на сериализацию объектов, не могут совместно использовать данные между этими различными реализациями. Эти приложения включают базу данных объектов MinneStore [42] и некоторые пакеты RPC . Решением этой проблемы является SIXX, [43] , который представляет собой пакет для нескольких Smalltalk, использующий формат на основе XML для сериализации.
Стандартная библиотека Swift предоставляет два протокола, Encodable
и Decodable
(объединенные вместе как Codable
), которые позволяют сериализовать или десериализовать экземпляры соответствующих типов из JSON , списков свойств или других форматов. [44] Реализации этих протоколов по умолчанию могут быть сгенерированы компилятором для типов, хранимые свойства которых также являются Decodable
или Encodable
.
PowerShell реализует сериализацию через встроенный командлет Export-CliXML
. Export-CliXML
сериализует объекты .NET и сохраняет полученный XML в файле. Чтобы восстановить объекты, используйте Import-CliXML
командлет , который генерирует десериализованный объект из XML в экспортированном файле. Десериализованные объекты, часто называемые «пакетами свойств», не являются живыми объектами; это моментальные снимки, имеющие свойства, но не имеющие методов. Двумерные структуры данных также могут быть (де)сериализованы в формате CSV с помощью встроенных командлетов Import-CSV
и Export-CSV
.
Это позволяет вам взять объект или группу объектов, поместить их на диск или отправить их через проводной или беспроводной транспортный механизм, а затем позже, возможно, на другом компьютере, обратить процесс, воскресив исходный объект(ы). Основные механизмы - сплющить объект(ы) в одномерный поток битов и превратить этот поток битов обратно в исходный объект(ы).
Сериализация, описанная ниже, является примером инструмента, используемого объектами внутри объектной системы для работы с графом, в который они встроены. Это, по-видимому, требует нарушения инкапсуляции, предоставляемой чистой объектной моделью.
Существует много видов сериализаторов; они производят очень компактные данные очень быстро. Существуют сериализаторы для обмена сообщениями, для хранения данных, для маршалинга объектов. Какой сериализатор является лучшим в .NET?
Наша реализация использует механизм, называемый «pickles», который будет выполнять преобразование между любой строго типизированной структурой данных и представлением этой структуры, подходящим для хранения в постоянных дисковых файлах. Операция Pickle.Write принимает указатель на строго типизированную структуру данных и доставляет буферы битов для записи на диск. Наоборот, Pickle.Read считывает буферы битов с диска и доставляет копию исходной структуры данных. (*) Это преобразование включает в себя идентификацию вхождений адресов в структуре и организацию того, чтобы при обратном считывании структуры с диска адреса заменялись адресами, допустимыми в текущей среде выполнения. Механизм pickle полностью автоматический: он управляется структурами типизации времени выполнения, которые присутствуют для нашего механизма сборки мусора. ... (*) Pickling очень похож на концепцию маршалинга в удаленных вызовах процедур. Но на самом деле наша реализация pickling работает только интерпретируя во время выполнения структуру динамически типизированных значений, в то время как наша реализация RPC работает только генерируя код для маршалинга статически типизированных значений. Каждое средство выиграло бы от добавления механизмов другого, но это еще не сделано.
названия «flattening»: поскольку я хочу оставить оригинальный модуль «marshal» в покое, а Джим жаловался, что «сериализация» также означает нечто совершенно иное, что на самом деле имеет значение в контексте
параллельного
доступа к постоянным объектам, с этого момента я буду использовать термин «flattening». ... (Система Modula-3 использует термин «консервированные» данные для этой концепции. Они, вероятно, уже решили все проблемы, причем в типобезопасной манере :-)