Spec-Zone.ru › Perl 5.34

Storable

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНТАКСИС
  • ОПИСАНИЕ
  • ХРАНЕНИЕ В ПАМЯТИ
  • КОНСУЛЬТАТИВНАЯ БЛОКИРОВКА
  • СКОРОСТЬ
  • КАНОНИЧЕСКОЕ ПРЕДСТАВЛЕНИЕ
  • ССЫЛКИ НА КОД
  • ВЕРСИОННАЯ СОСТОЯТЕЛЬНОСТЬ
  • ОТЧЕТ ОБ ОШИБКАХ
  • ТОЛЬКО ДЛЯ МАСТЕРОВ
    • Гачки
    • Предикаты
    • Рекурсия
    • Глубокое клонирование
  • Магия Storable
  • ПРИМЕРЫ
  • ПРЕДУПРЕЖДЕНИЕ О БЕЗОПАСНОСТИ
  • ПРЕДУПРЕЖДЕНИЕ
  • РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ
  • ОШИБКИ
    • Данные 64 бит в Perl 5.6.0 и 5.6.1
  • АВТОРЫ
  • АВТОР
  • СМОТРИТЕ ТАКЖЕ

ИМЯ

Storable - сохранение данных Perl-структур

СИНТАКСИС

use Storable;
store \%table, 'file';
$hashref = retrieve('file');

use Storable qw(nstore store_fd nstore_fd freeze thaw dclone);

# Network order
nstore \%table, 'file';
$hashref = retrieve('file');   # There is NO nretrieve()

# Storing to and retrieving from an already opened file
store_fd \@array, \*STDOUT;
nstore_fd \%table, \*STDOUT;
$aryref = fd_retrieve(\*SOCKET);
$hashref = fd_retrieve(\*SOCKET);

# Serializing to memory
$serialized = freeze \%table;
%table_clone = %{ thaw($serialized) };

# Deep (recursive) cloning
$cloneref = dclone($ref);

# Advisory locking
use Storable qw(lock_store lock_nstore lock_retrieve)
lock_store \%table, 'file';
lock_nstore \%table, 'file';
$hashref = lock_retrieve('file');

ОПИСАНИЕ

Пакет Storable обеспечивает сохранение ваших Perl-данных, содержащих SCALAR, ARRAY, HASH или REF объекты, т.е. всего, что удобно сохранить на диск и извлечь впоследствии.

Он может использоваться стандартным способом, вызывая store со ссылкой на сохраняемый объект и именем файла, куда нужно записать данные.

Процедура возвращает undef при проблемах ввода/вывода или других внутренних ошибках, в противном случае — истинное значение. Серьезные ошибки передаются как исключение die.

Для извлечения данных, сохраненных на диске, используйте retrieve с именем файла. Сохраненные объекты будут восстановлены в памяти, и будет возвращена ссылка на корневой объект. В случае ошибки ввода/вывода при чтении будет возвращено undef. Другие серьезные ошибки передаются через die.

Поскольку хранение выполняется рекурсивно, вы можете поместить ссылки на объекты, которые делят много общих данных, в один массив или хеш-таблицу, а затем сохранить этот объект. Таким образом, при извлечении всего объекта объекты будут по-прежнему делиться общими данными.

За счет небольшого накладных расходов на заголовки вы можете сохранять данные в уже открытый дескриптор файла с помощью store_fd и извлекать из файла с помощью fd_retrieve. Эти имена не импортируются по умолчанию, поэтому вам нужно будет сделать это явно, если они вам нужны. Дескриптор файла должен быть уже открыт, для чтения при извлечении и для записи при сохранении.

store_fd(\%table, *STDOUT) || die "can't store to stdout\n";
$hashref = fd_retrieve(*STDIN);

Вы также можете сохранять данные в сетевом порядке для облегчения обмена между платформами или при сохранении на сокете, известном как удаленный. Процедуры для вызова имеют префикс n для сети, как в nstore и nstore_fd. При извлечении данные будут правильно восстановлены, так что вам не нужно знать, восстанавливаются ли данные из родного или сетевого порядка. Двойные значения хранятся в строковом формате для обеспечения переносимости, с небольшой потерей точности в последних десятичных знаках.

Используя fd_retrieve, объекты извлекаются последовательно, по одному объекту (т.е. одному рекурсивному дереву) на связанный store_fd.

Если вы предпочитаете объектно-ориентированный подход, вы можете наследовать от Storable и напрямую сохранить свои объекты, вызвав store как метод. Тот факт, что корень сохраняемого дерева — это освященная ссылка (т.е. объект), является особым случаем, в котором извлечение не предоставляет ссылку на этот объект, а ссылку на сам освященный объект. (В противном случае вы получите ссылку на этот освященный объект).

ХРАНЕНИЕ В ПАМЯТИ

Движок Storable также может сохранять данные в скаляр Perl, чтобы позже их извлечь. Это используется главным образом для «замораживания» сложной структуры в безопасном компактном месте памяти (где ее, возможно, можно будет передать другому процессу через IPC, поскольку замораживание структуры фактически сериализует ее). Позже и, возможно, где-то в другом месте, вы можете «оттаять» скаляр Perl и воссоздать исходную сложную структуру в памяти.

Удивительно, но вызываемые процедуры называются freeze и thaw. Если вы хотите отправить замороженный скаляр на другую машину, используйте nfreeze для получения переносимой копии.

Обратите внимание, что замораживание и оттаивание структуры объекта фактически выполняет глубокое клонирование этой структуры:

dclone(.) = thaw(freeze(.))

Storable предоставляет dclone интерфейс, который не создает промежуточный скаляр, а вместо этого замораживает структуру во внутренней памяти и сразу же оттаивает ее.

КОНСУЛЬТАТИВНАЯ БЛОКИРОВКА

Процедуры lock_store и lock_nstore эквивалентны store и nstore, за исключением того, что они получают эксклюзивную блокировку файла перед записью. Аналогично, lock_retrieve делает то же самое, что и retrieve, но также получает общую блокировку файла перед чтением.

Как и в любой системе консультативной блокировки, защита работает только при систематическом использовании lock_store и lock_retrieve. Если одна часть вашего приложения использует store, а другая — lock_retrieve, никакой защиты не будет.

Внутренняя консультативная блокировка реализована с помощью процедуры Perl flock(). Если ваша система не поддерживает flock(), или вы используете файлы через NFS, вы можете использовать другие методы блокировки с помощью модулей, таких как LockFile::Simple, которые блокируют файл, используя запись в файловой системе, вместо блокировки дескриптора файла.

СКОРОСТЬ

Ядро Storable написано на C для достижения приемлемой скорости. Были реализованы дополнительные оптимизации на низком уровне при манипулировании внутренними структурами Perl, чтобы пожертвовать инкапсуляцией ради повышения скорости.

КАНОНИЧЕСКОЕ ПРЕДСТАВЛЕНИЕ

Обычно Storable сохраняет элементы хешей в порядке, в котором они хранятся Perl, т.е. псевдослучайном. Если вы зададите $Storable::canonical некоторое TRUE значение, Storable сохранит хеши с элементами, отсортированными по ключам. Это позволяет сравнивать структуры данных путем сравнения их замороженных представлений (или даже сжатых замороженных представлений), что может быть полезно для создания таблиц поиска для сложных запросов.

Канонический порядок не подразумевает сетевой порядок; это два независимых параметра.

ССЫЛКИ НА КОД

Начиная с версии Storable 2.05, ссылки на код могут сериализоваться с помощью B::Deparse. Для активации этой функции установите $Storable::Deparse в истинное значение. Для активации десериализации $Storable::Eval должно быть установлено в истинное значение. Имейте в виду, что десериализация выполняется через eval, что опасно, если файл Storable содержит вредоносные данные. Вы можете установить $Storable::Eval в ссылку на подпрограмму, которая будет использоваться вместо eval. См. пример ниже, использующий отсек Safe для десериализации ссылок на код.

Если $Storable::Deparse и/или $Storable::Eval установлены в ложные значения, то значение $Storable::forgive_me (см. ниже) учитывается при сериализации и десериализации.

ВЕРСИОННАЯ СОСТОЯТЕЛЬНОСТЬ

Эта версия Storable может использоваться с более новыми версиями Perl для сериализации данных, которые не поддерживаются более старыми версиями Perl. По умолчанию Storable попытается поступить правильно, croak() в случае столкновения с данными, которые невозможно десериализовать. Однако значения по умолчанию могут быть изменены следующим образом:

utf8 данные

Perl 5.6 добавил поддержку символов Юникода с кодовыми точками > 255, а Perl 5.8 полностью поддерживает символы Юникода в ключах хэшей. Perl внутренне кодирует строки с этими символами с использованием utf8, а Storable сериализует их как utf8. По умолчанию, если более старая версия Perl сталкивается со значением utf8, которое она не может представить, она croak(). Чтобы изменить это поведение, чтобы Storable десериализовал значения, закодированные в utf8, как строку байтов (эффективно удаляя флаг is_utf8), установите $Storable::drop_utf8 на некоторое TRUE значение. Это форма потери данных, поскольку с $drop_utf8 значением истинным становится невозможно определить, была ли исходные данные строкой Юникода или последовательностью байтов, которые случайно являются допустимым utf8.

ограниченные хэши

Perl 5.8 добавляет поддержку ограниченных хэшей, ключи которых ограничены заданным набором, а значения могут быть заблокированы для чтения только для чтения. По умолчанию, когда Storable сталкивается с ограниченным хэшем на perl, который их не поддерживает, он десериализует его как обычный хэш, бесшумно отбрасывая любые заполнительные ключи и оставляя ключи и все значения разблокированными. Чтобы заставить Storable croak() вместо этого, установите $Storable::downgrade_restricted на FALSE значение. Чтобы восстановить значение по умолчанию, верните его к TRUE значению.

Стратегия хэширования cperl PERL_PERTURB_KEYS_TOP имеет известную проблему с ограниченными хэшами.

большие объекты

В 64-битных системах некоторые структуры данных могут превышать предел 2 ГБ (т.е. I32_MAX). В 32-битных системах также строки между I32 и U32 (2 ГБ-4 ГБ). Начиная со Storable 3.00 (не в ядре perl5) мы можем хранить и извлекать эти объекты, даже если сам perl5 не может с ними справиться. Это строки длиннее 4 ГБ, массивы с более чем 2 ГБ элементов и хэши с более чем 2 ГБ элементов. cperl запрещает хэши с более чем 2 ГБ элементов, но в cperl это приводит к ошибке. Сам perl5, по крайней мере, до версии 5.26, позволяет это, но не может перебирать их. Обратите внимание, что создание таких объектов может вызвать исключения из-за нехватки памяти операционной системой до того, как perl сможет прервать процесс.

файлы из будущих версий Storable

Более ранние версии Storable сразу же выдавали ошибку, если они сталкивались с файлом с более высоким внутренним номером версии, чем тот, о котором знал читающий Storable. Внутренние номера версии увеличиваются каждый раз, когда к лексике формата файла добавляются новые типы данных (например, ограниченные хэши). Это означало, что более новая модуль Storable не могла записать файл, читаемый более старой версией Storable, даже если модуль-писатель не сохранял новые типы данных.

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

Старое поведение моментальной ошибки может быть восстановлено, установив $Storable::accept_future_minor на некоторое FALSE значение.

Все эти переменные не влияют на более новые версии Perl, которые поддерживают соответствующую функцию.

СООБЩЕНИЕ ОБ ОШИБКАХ

Storable использует парадигму «исключения», в которой не пытается обойти ошибки: если произойдет что-то плохое, генерируется исключение с точки зрения вызывающего кода (см. Carp и croak()). Используйте eval {}, чтобы перехватывать эти исключения.

Когда Storable генерирует ошибку, он пытается сообщить об ошибке с помощью функции logcroak() из пакета Log::Agent, если она доступна.

Обычные ошибки сообщаются тем, что store() или retrieve() возвращают undef. Такие ошибки обычно являются ошибками ввода-вывода (или ошибками усеченных потоков при извлечении).

Когда Storable генерирует ошибку «Превышен максимальный уровень рекурсии с вложенными структурами», у нас уже закончилось пространство стека. К сожалению, в некоторых более ранних версиях perl очистка рекурсивной структуры данных приводит к рекурсии в функциях освобождения, что приведет к переполнению стека во время очистки. В таком случае эта структура данных не очищается должным образом, она будет уничтожена только во время глобального уничтожения.

ТОЛЬКО ДЛЯ ЭКСПЕРТОВ

Вспомогательные функции

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

Так как мы уже говорили:

dclone(.) = thaw(freeze(.))

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

Поэтому, когда вовлечены вспомогательные функции сериализации,

dclone(.) <> thaw(freeze(.))

Ну, вы могли бы поддерживать их в синхронизации, но нет гарантии, что это всегда будет выполняться для классов, написанных другими людьми. Кроме того, в этом нет большой выгоды: вспомогательная функция сериализации могла бы сохранить только один атрибут объекта, что, вероятно, не должно происходить во время глубокого клонирования этого же объекта.

Вот интерфейс вспомогательных функций:

STORABLE_freeze obj, cloning

Вспомогательная функция сериализации, вызываемая для объекта во время сериализации. Она может наследоваться или определяться в самом классе, как и любой другой метод.

Аргументы: obj — объект для сериализации, cloning — флаг, указывающий, выполняем ли мы dclone() или обычную сериализацию через store() или freeze().

Возвращаемое значение: СПИСОК ($serialized, $ref1, $ref2, ...) , где $serialized — сериализованная форма для использования, а необязательные $ref1, $ref2 и т. д. — дополнительные ссылки, которые вы хотите передать механизму сериализации Storable.

При десериализации вам будет возвращён тот же СПИСОК, но все дополнительные ссылки будут указывать на десериализованную структуру.

В первый раз, когда вспомогательная функция вызывается в потоке сериализации, вы можете вернуть пустой список. Это сигнализирует механизму Storable об отказе от этой вспомогательной функции для данного класса и возвращении к стандартной сериализации базовых данных Perl. В следующий раз вспомогательная функция будет обработана как обычно.

Если вы не знаете лучшего, вспомогательная функция сериализации должна всегда возвращать:

sub STORABLE_freeze {
    my ($self, $cloning) = @_;
    return if $cloning;         # Regular default serialization
    ....
}

чтобы сохранить разумную семантику dclone().

STORABLE_thaw obj, cloning, serialized, ...

Вспомогательная функция десериализации, вызываемая для объекта во время десериализации. Но подождите: если мы десериализуем, разве объекта ещё нет?

Неправильно: механизм Storable создаёт пустой для вас. Если вы знаете Eiffel, вы можете рассматривать STORABLE_thaw как альтернативную функцию создания.

Это означает, что вспомогательная функция может наследоваться, как и любой другой метод, и что obj — это ваш освящённый указатель для этого конкретного экземпляра.

Другие аргументы должны быть знакомы, если вы знаете STORABLE_freeze: cloning — true, когда мы участвуем в операции глубокого клонирования, serialized — сериализованная строка, которую вы вернули механизму в STORABLE_freeze, и может быть необязательный список ссылок в том же порядке, что вы предоставили во время сериализации, указывающий на десериализованные объекты (которые были обработаны механизмом Storable).

Если механизм Storable не находит вспомогательную функцию STORABLE_thaw, он пытается загрузить класс, потребовав пакет динамически (используя имя освящённого пакета), а затем повторно пытается найти вспомогательную функцию. Если в этот момент вспомогательная функция не найдена, механизм генерирует ошибку. Обратите внимание, что этот механизм потерпит неудачу, если вы определите несколько классов в одном файле, но perlmod предупредил вас.

Вам нужно использовать эту информацию, чтобы заполнить obj так, как вы хотите.

Возвращаемое значение: ничего.

STORABLE_attach class, cloning, serialized

В то время как STORABLE_freeze и STORABLE_thaw полезны для классов, где каждый экземпляр является независимым, этот механизм испытывает трудности (или несовместим) с объектами, которые существуют как общие ресурсы процесса или системы, такие как синглтон-объекты, пулы баз данных, кэши или кешированные объекты.

Альтернативный метод STORABLE_attach предоставляет решение для этих общих объектов. Вместо STORABLE_freeze --> STORABLE_thaw, вы реализуете STORABLE_freeze --> STORABLE_attach вместо этого.

Аргументы: class — класс, который мы присоединяем, cloning — флаг, указывающий, выполняем ли мы dclone() или обычную десериализацию через thaw(), а serialized — сохранённая строка для объекта ресурса.

Поскольку эти объекты ресурсов считаются принадлежащими всему процессу/системе, а не «свойством» того, что сериализуется, никакие ссылки под объектом не должны включаться в сериализованную строку. Таким образом, в любом классе, реализующем STORABLE_attach, метод STORABLE_freeze не может возвращать никакие ссылки, а Storable будет выдавать ошибку, если STORABLE_freeze попытается вернуть ссылки.

Вся информация, необходимая для «присоединения» обратно к объекту общего ресурса, должна содержаться только в возвращаемой строке STORABLE_freeze. В противном случае, STORABLE_freeze ведёт себя как обычно для классов STORABLE_attach.

Поскольку STORABLE_attach получает класс (а не объект), он также возвращает объект напрямую, а не изменяя переданный объект.

Возвращаемое значение: объект типа class

Предикаты

Предикаты не экспортируются. Они должны вызываться путём явного указания имени пакета Storable.

Storable::last_op_in_netorder

Предикат Storable::last_op_in_netorder() сообщит вам, использовался ли сетевой порядок в последней операции store или retrieve. Если вы не знаете, как это использовать, просто забудьте об этом.

Storable::is_storing

Возвращает true, если выполняется операция store (через вспомогательную функцию STORABLE_freeze).

Storable::is_retrieving

Возвращает true, если выполняется операция retrieve (через вспомогательную функцию STORABLE_thaw).

Рекурсия

Вспомогательные функции дают возможность рекурсивно обратиться к механизму Storable. Действительно, вспомогательные функции — это обычный Perl-код, и Storable удобен при сериализации и десериализации, так почему бы не использовать его для обработки строки сериализации?

Однако, есть несколько моментов, которые нужно знать:

  • От Storable 3.05 до 3.13 мы искали предел рекурсии стека для ссылок, массивов и хешей до максимальной глубины ~1200-35000, иначе мы могли попасть в ошибку стека. В JSON::XS этот предел составляет 512. Со ссылками, которые не ссылаются друг на друга немедленно, пока такого предела нет, поэтому вы можете столкнуться с такой ошибкой стека segfault.

    У этих проверок и проверок, которые мы выполнили, есть некоторые ограничения:

    • Размер стека во время компиляции может отличаться от размера стека во время выполнения, например, размер стека может быть изменён с помощью ulimit(1). Если он больше во время выполнения, Storable может неправильно завершить работу freeze() или thaw(). Если он больше во время компиляции, Storable может получить ошибку segmentation fault при обработке глубокой структуры во время выполнения.

    • Размер стека может отличаться в потоке.

    • Пределы рекурсии для массивов и хешей проверяются отдельно по отношению к той же глубине рекурсии, замороженная структура с большой последовательностью вложенных массивов внутри многих вложенных хешей может исчерпать стек процессора, не вызвав защиты от рекурсии Storable.

    Поэтому теперь они имеют простые значения по умолчанию вместо проверки во время компиляции.

    Вы можете контролировать максимальную глубину рекурсии массивов и хешей, изменив $Storable::recursion_limit и $Storable::recursion_limit_hash соответственно. Любое из них может быть установлено в -1 для предотвращения проверок глубины, хотя это не рекомендуется.

    Если вы хотите проверить, каковы пределы, инструмент stacksize включен в дистрибутив Storable.

  • Вы можете создать бесконечные циклы, если вещи, которые вы сериализуете с помощью freeze() (например), ссылаются обратно на объект, который мы пытаемся сериализовать в обработчике.

  • Общие ссылки между объектами не останутся общими: если мы сериализуем список объектов [A, C], где объект A и C ссылаются на ОДИН и тот же объект B, и если есть обработчик сериализации в A, который говорит freeze(B), то при десериализации мы получим [A', C'], где A' ссылается на B', но C' ссылается на D, глубокую копию B'. Топология не сохранилась.

  • Максимальный предел рекурсии стека для вашей системы возвращается stack_depth() и stack_depth_hash(). Предел для хешей обычно составляет половину размера предела массивов и ссылок, так как API хешей Perl не оптимален.

Вот почему STORABLE_freeze позволяет вам предоставить список ссылок для сериализации. Движок гарантирует, что они будут сериализованы в том же контексте, что и другие объекты, и, следовательно, что общие объекты останутся общими.

В примере [A, C] выше обработчик STORABLE_freeze мог бы вернуть:

("something", $self->{B})

и часть B была бы сериализована движком. В STORABLE_thaw вы бы получили ссылку на объект B', десериализованный для вас.

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

Глубокое клонирование

В модуле Clone, доступном в CPAN, реализовано глубокое клонирование напрямую, то есть без заморозки в памяти и разморозки результата. В какой-то момент он призван заменить dclone() в Storable. Однако в настоящее время он не поддерживает обработчики Storable для переопределения способа выполнения глубокого клонирования.

Магия Storable

Да, много этого :-) Но точнее, в системах UNIX есть утилита file, которая распознаёт файлы данных по их содержимому (обычно их первым нескольким байтам). Для этого определённый файл под названием magic должен быть обучен подписи данных. Где находится этот файл конфигурации, зависит от типа UNIX; часто это что-то вроде /usr/share/misc/magic или /etc/magic. Вашему системному администратору нужно обновить файл magic. Необходимая информация о подписи выводится в стандартный вывод при вызове Storable::show_file_magic(). Обратите внимание, что в реализации GNU утилиты file, версии 3.38 или более поздней, ожидается наличие поддержки распознавания файлов Storable "из коробки" помимо других типов файлов Perl.

Вы также можете использовать следующие функции для извлечения информации о заголовке файла из изображений Storable:

$info = Storable::file_magic( $filename )

Если данный файл является изображением Storable, вернуть хеш, описывающий его. Если файл читаемый, но не является изображением Storable, вернуть undef. Если файл не существует или недоступен для чтения, выдать ошибку.

Возвращаемый хеш содержит следующие элементы:

version

Возвращает версию формата файла. Это строка типа "2.7".

Обратите внимание, что этот номер версии не совпадает с номером версии самого модуля Storable. Например, Storable v0.7 создаёт файлы в формате v2.0, а Storable v2.15 создаёт файлы в формате v2.7. Номер версии формата файла увеличивается только тогда, когда добавляются дополнительные функции, которые могли бы сбить с толку более старые версии модуля.

У файлов, более ранних чем v2.0, будет один из номеров версии "-1", "0" или "1". В то время не использовались номера версий.

version_nv

Возвращает версию формата файла как число. Это строка типа "2.007". Это значение подходит для числовых сравнений.

Функция-константа Storable::BIN_VERSION_NV возвращает сопоставимое число, которое представляет собой наибольший номер версии файла, который эта версия Storable полностью поддерживает (но см. обсуждение $Storable::accept_future_minor выше). Функция-константа Storable::BIN_WRITE_VERSION_NV возвращает версию файла, которая может быть меньше Storable::BIN_VERSION_NV в некоторых конфигурациях.

major, minor

Также возвращает версию формата файла. Если версия "2.7", то major будет 2, а minor будет 7. Элемент minor отсутствует, когда major меньше 2.

hdrsize

Это количество байтов, занимаемых заголовком Storable.

netorder

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

byteorder

Это присутствует только когда netorder FALSE. Это строка $Config{byteorder} perl, который создал это изображение. Это строка типа "1234" (32-битный малый порядок) или "87654321" (64-битный большой порядок). Она должна соответствовать текущему perl для того, чтобы изображение было читаемым Storable.

intsize, longsize, ptrsize, nvsize

Они присутствуют только когда netorder FALSE. Это размеры различных C-типов данных perl, который создал это изображение. Они должны соответствовать текущему perl, для того чтобы изображение было читаемым Storable.

Элемент nvsize присутствует только для формата файла v2.2 и выше.

file

Имя файла.

$info = Storable::read_magic( $buffer )
$info = Storable::read_magic( $buffer, $must_be_file )

Переменная $buffer должна содержать изображение Storable или первые несколько байтов. Если $buffer начинается с заголовка Storable, то возвращается хеш, описывающий изображение, в противном случае возвращается undef.

Хеш имеет ту же структуру, что и возвращаемый Storable::file_magic(). Элемент file равен TRUE, если изображение представляет собой файл.

Если аргумент $must_be_file присутствует и равен TRUE, то возвращается undef, если изображение не похоже на дамп файла.

Максимальный размер заголовка Storable в настоящее время составляет 21 байт. Если предоставленный $buffer содержит только часть изображения Storable, он должен быть, по крайней мере, такой длины, чтобы read_magic() распознал его как таковой.

ПРИМЕРЫ

Ниже приведены примеры кода, показывающие возможный способ использования Storable:

use Storable qw(store retrieve freeze thaw dclone);

%color = ('Blue' => 0.1, 'Red' => 0.8, 'Black' => 0, 'White' => 1);

store(\%color, 'mycolors') or die "Can't store %a in mycolors!\n";

$colref = retrieve('mycolors');
die "Unable to retrieve from mycolors!\n" unless defined $colref;
printf "Blue is still %lf\n", $colref->{'Blue'};

$colref2 = dclone(\%color);

$str = freeze(\%color);
printf "Serialization of %%color is %d bytes long.\n", length($str);
$colref3 = thaw($str);

что печатает (на моём компьютере):

Blue is still 0.100000
Serialization of %color is 102 bytes long.

Сериализация ссылок CODE и десериализация в безопасном отделении:

use Storable qw(freeze thaw);
use Safe;
use strict;
my $safe = new Safe;
       # because of opcodes used in "use strict":
$safe->permit(qw(:default require));
local $Storable::Deparse = 1;
local $Storable::Eval = sub { $safe->reval($_[0]) };
my $serialized = freeze(sub { 42 });
my $code = thaw($serialized);
$code->() == 42;

ПРЕДУПРЕЖДЕНИЕ О БЕЗОПАСНОСТИ

Не принимайте документы Storable из ненадежных источников!

Некоторые функции Storable могут привести к уязвимостям безопасности, если вы принимаете документы Storable из ненадежных источников с флагами по умолчанию. Наиболее очевидным является возможность передачи кода в процесс десериализации благодаря опциональной (по умолчанию выключенной) функции сериализации ссылок CODE. Кроме того, любой сериализованный объект заставит Storable загрузить модуль, соответствующий классу объекта, в модуль десериализации. Для подменённых имён модулей это может загрузить почти произвольный код. Наконец, деструкторы десериализованного объекта будут вызваны при уничтожении объектов в процессе десериализации. Злонамеренно созданные документы Storable могут поместить такие объекты в значение ключа хеша, который перезаписывается другой парой ключ/значение в том же хеше, вызывая немедленное выполнение деструктора.

Чтобы отключить благословение объектов при разморозке/получении, удалите флаг BLESS_OK = 2 из $Storable::flags или установите второй аргумент для thaw/retrieve в 0.

Чтобы отключить привязку данных при разморозке/получении, удалите флаг TIE_OK = 4 из $Storable::flags или установите второй аргумент для thaw/retrieve в 0.

При стандартном значении $Storable::flags = 6 создание или уничтожение случайных объектов, даже переименованных объектов, может быть под контролем злоумышленника. См. CVE-2015-1592 и его модуль metasploit.

Если ваше приложение требует приёма данных из ненадежных источников, лучше использовать менее мощный и более безопасный формат и реализацию сериализации. Если ваши данные достаточно простые, Cpanel::JSON::XS, Data::MessagePack или Sereal — лучшие варианты и обеспечивают максимальную совместимость, но имейте в виду, что Sereal по умолчанию небезопасен.

ПРЕДУПРЕЖДЕНИЕ

Если вы используете ссылки в качестве ключей в своих хеш-таблицах, вы будете разочарованы при получении данных. Действительно, Perl строит ссылки, используемые в качестве ключей хеш-таблиц. Если вы хотите позже получить доступ к элементам по другой строке ссылки (т.е. используя ту же ссылку, которая использовалась для ключа для записи значения в хеш-таблицу), это сработает, потому что обе ссылки строятся в одну и ту же строку.

Однако это не будет работать при последовательности операций store и retrieve, так как адреса в полученных объектах, которые являются частью строковых ссылок, вероятно, будут отличаться от исходных адресов. Топология вашей структуры сохраняется, но не скрытые семантические значения, такие как эти.

В платформах, где это важно, убедитесь, что вы вызываете binmode() для описателей, которые передаёте функциям Storable.

Хранение данных в канонической форме, содержащих большие хеши, может быть значительно медленнее, чем хранение тех же данных в обычном формате, так как необходимо выделять, заполнять, сортировать и освобождать временные массивы для хранения ключей каждого хеша. Некоторые тесты показали сокращение скорости хранения данных вдвое — точная величина накладных расходов будет зависеть от сложности ваших данных. Замедления при получении данных нет.

РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ

Библиотека Storable теперь имеет экспериментальную поддержку хранения регулярных выражений, но существуют значительные ограничения:

  • Требуется perl 5.8 или более поздняя версия.

  • Регулярные выражения с блоками кода, например, /(?{ ... })/ или /(??{ ... })/, будут выбрасывать исключение при размораживании.

  • Синтаксис и флаги регулярных выражений изменялись на протяжении истории perl, поэтому регулярное выражение, замороженное в одной версии perl, может не разморозиться или работать по-другому в другой версии perl.

  • В зависимости от версии perl, поведение регулярных выражений может меняться в зависимости от контекста, но более поздние версии perl включают это поведение в сам regexp.

Библиотека Storable выбросит исключение, если замороженное регулярное выражение не удастся разморозить.

ОШИБКИ

Нельзя хранить GLOB, FORMLINE и т. д. Если вы можете определить семантику для этих операций, смело улучшайте Storable, чтобы он мог с ними работать.

Функции сохранения croak при столкновении с такими ссылками, если вы не установите $Storable::forgive_me на некоторое значение TRUE. В этом случае сообщение об ошибке преобразуется в предупреждение, и вместо него будет сохранён некий бессмысленный строковый текст.

Установление $Storable::canonical может привести к замороженным строкам, которые не будут сравниваться как равные, из-за возможной строковой интерпретации чисел. Если существует строковая версия скаляра, используется именно она; следовательно, если вы будете использовать числа как строки между двумя операциями заморозки одних и тех же структур данных, вы получите разные результаты.

При хранении чисел с плавающей запятой в сетевом порядке их значение сохраняется как текст. Однако не следует ожидать, что нечисловые значения с плавающей запятой, такие как бесконечность и «не число», успешно пройдут через пару nstore()/retrieve().

Библиотека Storable не знает и не заботится о наборах символов (хотя она знает, что символы могут быть шире восьми бит), поэтому любые различия в интерпретации кодов символов между хостом и целевой системой — ваша проблема. В частности, если хост и целевая система используют разные кодовые точки для представления символов, используемых в текстовом представлении чисел с плавающей запятой, вы не сможете обмениваться данными с плавающей запятой, даже с помощью nstore().

Storable::drop_utf8 — грубый инструмент. Нет возможности вернуть все строки как последовательности utf8 или попытаться преобразовать данные utf8 обратно в 8-битные и croak() в случае неудачи преобразования.

До версии Storable 2.01 не было различия между знаковыми и беззнаковыми целыми числами при хранении. По умолчанию Storable предпочитает сохранять строковое представление скаляра (если оно есть), поэтому это будет вызывать проблемы только при хранении больших беззнаковых целых чисел, которые никогда не были преобразованы в строку или число с плавающей запятой. Другими словами, это значения, которые были сгенерированы целочисленными операциями, такими как логические операции, и затем не использовались ни в каком строковом или арифметическом контексте до хранения.

Данные 64-битного размера в perl 5.6.0 и 5.6.1

Этот раздел касается только вас, если у вас есть данные, записанные с помощью Storable 2.02 или более ранней версии в perl 5.6.0 или 5.6.1 на Unix или Linux, которые были сконфигурированы с поддержкой 64-битных целых чисел (не по умолчанию). Если вы использовали предварительно скомпилированный perl, а не запускали Configure для сборки собственного perl из исходного кода, то это, скорее всего, вас не коснется, и вы можете прекратить чтение (если вас это не интересует). Если вы используете perl на Windows, это вас не затронет.

Storable записывает заголовок файла, содержащий размеры различных типов данных языка C для компилятора C, который построил Storable (когда запись не производится в сетевом порядке), и откажется загрузить файлы, записанные с помощью Storable на другом (или несовместимом) архитектурном устройстве. Эта проверка и проверка порядка байтов машины необходимы, так как размеры различных полей в файле определяются размерами типов данных языка C, и поэтому файлы, записанные на разных архитектурах, несовместимы. Это делается для повышения скорости. (При записи в сетевом порядке все поля записываются в стандартной длине, что обеспечивает полную взаимозаменяемость, но при чтении и записи требуется больше времени)

Perl 5.6.x предоставил возможность по желанию настроить интерпретатор perl для использования типа C long long для хранения 64-битных целых чисел на 32-битных системах. Однако из-за того, как система конфигурации Perl генерировала файлы конфигурации C на платформах, не являющихся Windows, и способа, которым Storable генерирует свой заголовок, ничего в заголовке файла Storable не отражало, использовал ли perl при записи 32- или 64-битные целые числа, несмотря на то, что Storable хранил некоторые данные в файле по-разному. Следовательно, Storable, работающий в perl с 64-битными целыми числами, прочтёт заголовок из файла, записанного 32-битным perl, не поймёт, что данные фактически имеют немного несовместимый формат, и затем попадёт в серьёзные неприятности (возможно, сбой), если столкнётся с сохранённым целым числом. Это ошибка проектирования.

Теперь Storable изменён так, чтобы записывать и считывать заголовок файла с информацией о размере целых чисел. Невозможно определить, был ли старый файл, который считывается, записан с 32- или 64-битными целыми числами (у них один и тот же заголовок), поэтому невозможно автоматически переключиться на правильный режим обратной совместимости. Таким образом, Storable по умолчанию использует новое правильное поведение.

Это означает, что если у вас есть данные, записанные Storable 1.x, запущенным в perl 5.6.0 или 5.6.1, настроенном с 64-битными целыми числами на Unix или Linux, то по умолчанию Storable откажется от их чтения, выдав ошибку Порядок байтов не совместим. Если у вас есть такие данные, вы должны установить $Storable::interwork_56_64bit в значение true, чтобы этот Storable читал и записывал файлы со старым заголовком. Вам также необходимо перенести свои данные или любой более старый perl, с которым вы взаимодействуете, на эту текущую версию Storable.

Если у вас нет данных, записанных с использованием указанной выше конфигурации perl, то вам ничего не нужно делать и не следует ничего делать. Не устанавливайте флаг — Storable в идентично настроенном perl не только откажется от их загрузки, но Storable в разных настроенных perl загрузит их, полагая, что они правильные для него, а затем может потерпеть неудачу или завершиться сбоем на этапе чтения.

АВТОРСКИЕ ПРАВА

Спасибо (в хронологическом порядке):

Jarkko Hietaniemi <jhi@iki.fi>
Ulrich Pfeifer <pfeifer@charly.informatik.uni-dortmund.de>
Benjamin A. Holzman <bholzman@earthlink.net>
Andrew Ford <A.Ford@ford-mason.co.uk>
Gisle Aas <gisle@aas.no>
Jeff Gresham <gresham_jeffrey@jpmorgan.com>
Murray Nesbitt <murray@activestate.com>
Marc Lehmann <pcg@opengroup.org>
Justin Banks <justinb@wamnet.com>
Jarkko Hietaniemi <jhi@iki.fi> (AGAIN, as perl 5.7.0 Pumpkin!)
Salvador Ortiz Garcia <sog@msg.com.mx>
Dominic Dunlop <domo@computer.org>
Erik Haugan <erik@solbors.no>
Benjamin A. Holzman <ben.holzman@grantstreet.com>
Reini Urban <rurban@cpan.org>
Todd Rinaldo <toddr@cpanel.net>
Aaron Crane <arc@cpan.org>

за их сообщения об ошибках, предложения и вклад.

Benjamin Holzman внес вклад в поддержку привязанных переменных, Andrew Ford — в канонический порядок хешей, а Gisle Aas исправил несколько моих заблуждений относительно внутренней структуры perl и оптимизировал вывод «меток» в выходных потоках, просто посчитав объекты вместо их маркировки (что привело к двоичной несовместимости для изображения Storable, начиная с версии 0.6 — более старые изображения, конечно, всё ещё правильно понимаются). Murray Nesbitt сделал Storable потокобезопасным. Marc Lehmann добавил поддержку перегрузки и ссылок на привязанные элементы. Benjamin Holzman добавил улучшение производительности для перегруженных классов; спасибо Grant Street Group за финансирование. Reini Urban принял на себя обслуживание с p5p и добавил исправления безопасности и поддержку огромных объектов.

АВТОР

Storable был написан Raphael Manfredi <Raphael_Manfredi@pobox.com> Сейчас поддержка осуществляется с помощью cperl http://perl11.org/cperl

Пожалуйста, пишите нам с проблемами, исправлениями ошибок, комментариями и жалобами, хотя если у вас есть комплименты, отправьте их Raphael. Не пишите Raphael с проблемами, так как он больше не работает со Storable, и ваше сообщение будет задерживаться, пока он не перешлёт его нам.

СМОТРИТЕ ТАКЖЕ

Clone.

© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.34.0/Storable

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API