Spec-Zone.ru › Perl 5.30

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

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

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

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

:utf8

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

(ВНИМАНИЕ: этот слой не проверяет последовательности байтов. Для чтения входных данных следует вместо этого использовать :encoding(UTF-8) вместо простого :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. В определённых ситуациях это может быть быстрее для больших файлов и может привести к меньшему использованию физической памяти, когда несколько процессов читают один и тот же файл.

Файлы, которые недоступны для mmap(), ведут себя как слой :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);

(Обычно слои одинаковы с обеих сторон файлового дескриптора, но, например, с сокетами могут быть различия, или если вы использовали pragma 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.30.3/PerlIO

Spec-Zone.ru

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