PerlIO
СОДЕРЖАНИЕ
ИМЯ
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