Spec-Zone.ru › Perl 5.28

PerlIO

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНОПСИС
  • ОПИСАНИЕ
    • Пользовательские слои
    • Альтернативы raw
    • Значения по умолчанию и как их переопределить
    • Запрос слоёв дескрипторов файлов
  • АВТОР
  • СМОТРИТЕ ТАКЖЕ

ИМЯ

PerlIO - загрузчик по требованию для слоёв PerlIO и корень пространства имён PerlIO::*

СИНОПСИС

open($fh, "<:crlf", "my.txt"); # support platform-native and 
                               # CRLF text files

open($fh, "<", "his.jpg"); # portably open a binary file for reading
binmode($fh);

Shell:
  PERLIO=perlio perl ....

ОПИСАНИЕ

При встрече неопределённого слоя 'foo' в спецификации слоёв open или binmode код C выполняет эквивалент:

use PerlIO 'foo';

Затем код Perl в PerlIO.pm пытается найти слой, выполнив

require PerlIO::foo;

В противном случае пакет PerlIO является заглушкой для дополнительных функций, связанных с PerlIO.

В настоящее время определены следующие слои:

:unix

Низкоуровневый слой, который предоставляет базовые операции PerlIO в терминах вызовов числовых дескрипторов файлов UNIX/POSIX (open(), read(), write(), lseek(), close()).

:stdio

Слой, который вызывает fread, fwrite и fseek/ftell и т. д. Обратите внимание, что, поскольку это «реальный» stdio, он игнорирует любые слои под ним и переходит напрямую к операционной системе через библиотеку C, как обычно.

:perlio

Полностью реализованная буферизация для PerlIO. Обеспечивает быстрый доступ к буферу для sv_gets , который реализует perl's readline/<> и в общем стремится минимизировать копирование данных.

:perlio вставит слой :unix ниже себя для выполнения низкоуровневого ввода-вывода.

:crlf

Слой, который реализует окончания строк CRLF, аналогичные DOS/Windows. При чтении преобразует пары CR, LF в один символ новой строки «\n». При записи преобразует каждую «\n» в пару CR, LF. Обратите внимание, что этот слой молча откажется от размещения поверх себя.

В настоящее время он не имитирует MS-DOS в отношении обработки Control-Z как маркера конца файла.

Основан на слое :perlio.

:utf8

Указывает, что поток принимает внутреннее кодирование символов Perl. (На машинах ASCII это действительно UTF-8, но на машинах EBCDIC — UTF-EBCDIC.) Это позволяет читать или писать в поток любой символ, который может представлять Perl. Кодировка UTF-X выбрана для отображения простых текстовых частей (то есть букв без диакритики, цифр и распространённых знаков препинания) в кодированном файле в удобочитаемом виде.

(ВНИМАНИЕ: Этот слой не проверяет последовательности байтов. Для чтения входных данных используйте вместо простого :utf8.

Вот как записать свои исходные данные в UTF-8 (или UTF-EBCDIC) и затем прочитать их обратно.

open(F, ">:utf8", "data.utf");
print F $out;
close(F);

open(F, "<:utf8", "data.utf");
$in = <F>;
close(F);
:bytes

Это обратный слой к слою :utf8. Он отключает флаг в подлежащем слое, чтобы данные, считываемые из него, считались «октовыми», то есть только символами в диапазоне 0..255. Аналогично при выводе Perl предупредит, если символ «ширины» будет записан в такой поток.

:raw

Слой :raw определяется как идентичный вызову binmode($fh) — поток делается подходящим для передачи двоичных данных, то есть каждый байт передаётся как есть. Поток всё ещё будет буферизован.

В Perl 5.6 и некоторых книгах слой :raw (ранее иногда также назывался «дисциплиной») документируется как обратный слою :crlf. Это больше не так — другие слои, которые изменяют двоичный характер потока, также отключены. Если вам нужны окончания строк UNIX на платформе, которая обычно выполняет преобразование CRLF, но при этом вам нужны UTF-8 или кодировки по умолчанию, необходимо добавить :perlio в переменную среды PERLIO.

Реализация :raw — как псевдослой, который при «размещении» извлекает себя и любые слои, не объявляющие себя подходящими для двоичных данных. (Отмена :utf8 и :crlf реализуется путём сброса флагов, а не извлечения слоёв, но это деталь реализации.)

Вследствие того, что :raw обычно извлекает слои, обычно он имеет смысл только как единственный или первый элемент в спецификации слоя. При использовании в качестве первого элемента он обеспечивает известную базу для построения, например:

open($fh,":raw:utf8",...)

будет строить «двоичный» поток, но затем включит преобразование UTF-8.

:pop

Псевдослой, который удаляет верхний слой. Даёт коду Perl способ манипулирования стеком слоёв. Обратите внимание, что :pop работает только со слоями и не отменит эффекты псевдослоёв, таких как :utf8. Пример возможного использования:

open($fh,...)
...
binmode($fh,":encoding(...)");  # next chunk is encoded
...
binmode($fh,":pop");            # back to un-encoded

Необходим более элегантный (и безопасный) интерфейс.

:win32

На платформах Win32 этот экспериментальный слой использует родной ввод-вывод «обработчика» вместо низкоуровневого слоя числового дескриптора файла, аналогичного UNIX. Известно, что он подвержен ошибкам по состоянию на Perl 5.8.2.

Пользовательские слои

Возможна разработка пользовательских слоёв в дополнение к встроенным, как в C/XS, так и в Perl. Два таких слоя (и один пример, написанный на Perl с использованием последнего) поставляются с дистрибутивом Perl.

:encoding

Используйте :encoding(ENCODING) в open() или binmode(), чтобы установить слой, который прозрачно выполняет преобразования наборов символов и кодировок, например, от Shift-JIS к Unicode. Обратите внимание, что под stdio :encoding также включает :utf8. Для получения дополнительной информации см. PerlIO::encoding.

:mmap

Слой, который реализует «чтение» файлов с использованием mmap() для отображения (всего) файла в адресном пространстве процесса, а затем использование его в качестве «буфера» PerlIO. В определённых обстоятельствах это может быть быстрее для больших файлов и может привести к меньшему использованию физической памяти при одновременном чтении одного и того же файла несколькими процессами.

Файлы, которые нельзя отобразить, ведут себя как слой :perlio. Запись также ведёт себя как слой :perlio, так как mmap() для записи требует дополнительного обслуживания (для расширения файла), что нивелирует любое преимущество.

Слой :mmap не будет существовать, если платформа не поддерживает mmap().

:via

Используйте :via(MODULE) в open() или binmode(), чтобы установить слой, который выполняет любые преобразования (например, сжатие/распаковку, шифрование/дешифрование) с дескриптором файла. Для получения дополнительной информации см. PerlIO::via.

Альтернативы raw

Для получения двоичного потока можно использовать альтернативный метод:

open($fh,"whatever")
binmode($fh);

Это имеет преимущество обратной совместимости с тем, как такие вещи приходилось кодировать на некоторых платформах в течение многих лет.

Чтобы получить небуферизованный поток, укажите небуферизованный слой (например, :unix) в вызове open:

open($fh,"<:unix",$path)

Значения по умолчанию и как их переопределить

Если платформа похожа на MS-DOS и обычно выполняет преобразование CRLF в «\n» для текстовых файлов, то слои по умолчанию следующие:

unix crlf

(Низкоуровневый слой «unix» может быть заменён платформенно-специфическим низкоуровневым слоем.)

В противном случае, если Configure выяснил, как выполнить «быстрый» ввод-вывод, используя системный stdio, то слои по умолчанию:

unix stdio

В противном случае слои по умолчанию:

unix perlio

Эти значения по умолчанию могут измениться после лучшей проверки и настройки PerlIO.

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

Это можно использовать для наблюдения за эффектом/ошибками в различных слоях, например:

cd .../perl/t
PERLIO=stdio  ./perl harness
PERLIO=perlio ./perl harness

Для различных значений PERLIO см. "PERLIO" в perlrun.

Запрос слоёв дескрипторов файлов

Следующее возвращает имена слоёв PerlIO в дескрипторе файла.

my @layers = PerlIO::get_layers($fh); # Or FH, *FH, "FH".

Слои возвращаются в порядке, в котором их использует вызов open() или binmode(). Обратите внимание, что «стек по умолчанию» зависит от операционной системы и версии Perl, а также от конфигураций Perl во время компиляции и выполнения.

В следующей таблице обобщены слои по умолчанию на платформах UNIX-подобных и DOS-подобных платформах и в зависимости от значения $ENV{PERLIO}:

PERLIO     UNIX-like                   DOS-like
------     ---------                   --------
unset / "" unix perlio / stdio [1]     unix crlf
stdio      unix perlio / stdio [1]     stdio
perlio     unix perlio                 unix perlio

# [1] "stdio" if Configure found out how to do "fast stdio" (depends
# on the stdio implementation) and in Perl 5.8, otherwise "unix perlio"

По умолчанию возвращаются слои со стороны входного потока дескриптора файла; для получения слоёв со стороны вывода используйте необязательный аргумент output:

my @layers = PerlIO::get_layers($fh, output => 1);

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

Функций set_layers() нет, и get_layers() не возвращает связанный массив, отражающий стек, или что-то подобное. Это не случайно или непреднамеренно. Стек слоёв PerlIO немного сложнее, чем просто стек (см., например, поведение :raw). Вы должны использовать open() и binmode() для манипулирования стеком.

Следуют детали реализации, пожалуйста, закройте глаза.

Аргументы слоёв по умолчанию возвращаются в скобках после имени слоя, а некоторые слои (например, utf8) не являются реальными слоями, а вместо этого представляют флаги реальных слоёв; чтобы получить все эти возвращаемые значения отдельно, используйте необязательный аргумент details:

my @layer_and_args_and_flags = PerlIO::get_layers($fh, details => 1);

Результат будет вплоть до трёх раз больше количества слоёв: первый элемент будет именем, второй элемент — аргументами (неуказанные аргументы будут undef), третий элемент — флагами, четвёртый элемент — снова именем и так далее.

Теперь вы можете открыть глаза.

АВТОР

Nick Ing-Simmons <nick@ing-simmons.net>

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

"binmode" в perlfunc, "open" в perlfunc, perlunicode, perliol, Encode

© 1993–2020 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.28.3/PerlIO

Spec-Zone.ru

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