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
-
Слой, который реализует окончания строк 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