binmode
- binmode FILEHANDLE, LAYER
- binmode FILEHANDLE
Устанавливает дескриптор FILEHANDLE для чтения или записи в "бинарный" или "текстовый" режимы в системах, библиотеки времени исполнения которых различают текстовые и двоичные данные. Если FILEHANDLE представляет собой выражение, то его значение принимается за имя дескриптора файла. Функция возвращает значение "истина" в случае успеха, в противном случае возвращает
undef, а переменной$!присваивается сообщение об ошибке.В некоторых системах (обычно в системах DOS и Windows) необходимо использовать binmode(), когда вы работаете не с текстовым файлом. В целях портативности будет хорошей практикой всегда использовать ее при необходимости, и никогда не использовать там, где она не подходит. Кроме того, люди могут устанавливать свои режимы ввода-вывода по умолчанию для UTF-8 закодированных данных, а не байтов.
Другими словами, независимо от платформы, используйте binmode() над бинарными данными, например такими, как изображения.
Если указан уровень LAYER, он является одной строкой, но может содержать несколько директив. Директивы изменяют поведение дескриптора. Когда LAYER указан, использование binmode над текстовым файлом имеет смысл.
Если LAYER опущен или указан как
:raw,то дескриптор файла становится пригодным для передачи бинарных данных. Это включает в себя отключение возможных переводов CRLF и маркировки его как байт (в отличие от символов Юникода). Отметим, что несмотря на то, что может подразумеваться в "Программирование на Perl" (Камел, 3-е издание) или где-либо еще,:rawне просто обратна:crlf. Другие уровни, которые могут повлиять на бинарный характер потока также отключены. См. PerlIO, perlrun и обсуждение переменной среды PERLIO.Директивы
:bytes,:crlf,:utf8и любые другие директивы в форме:...называются уровнями(layers) ввода-вывода. Для установки уровней ввода-вывода по умолчанию можно использовать прагмуopen. См. open.Параметр LAYER функции binmode() описывается как "Дисциплина" в книге "Программирование на Perl, 3-го издания. Однако, с тех пор консенсус именования данной функциональности сместилась с "дисциплина" на "уровень". По этой причине в документации текущей версии Perl мы используем понятие "уровни", а не "дисциплины".
Чтобы отметить FILEHANDLE как UTF-8, используйте
:utf8или:encoding(utf8).:utf8только помечает данные как UTF-8 без дополнительной проверки, в то время как:encoding(utf8)проверяет данные на фактическую валидность UTF-8. Подробности можно найти в PerlIO::encoding.В общем, binmode() должен вызываться после open(), но до операций ввода-вывода над дескриптором файла. Вызов binmode() обычно сбрасывает любые ожидающие буферизованные данные вывода (и, возможно, ожидающие данные ввода) дескриптора. Исключением является уровень
:encoding, который изменяет для дескриптора кодировку по умолчанию, см "open". Уровень:encodingиногда необходимо вызывать в середине потока и это не сбрасывает поток.:encodingтакже неявно задействует уровень:utf8, поскольку внутренне Perl оперирует над utf-8 кодированными символами.Операционная система, драйверы устройств, библиотеки C и система времени исполнения Perl работают вместе, чтобы дать возможность программисту использовать один символ (
\n) как конец строки, независимо от внешнего представления. На многих операционных системах, простой текстовый файл соответствует внутреннему представлению, но на некоторых платформах внешнее представление\nсостоит из более, чем одного символа.Mac OS, все вариации Unix и файлы Stream_LF в VMS используют один символ конца каждой строки во внешнем представлении текста (даже, если это один символ возврата каретки в Mac OS и перевода строки в Unix и в большинстве VMS файлов). В других системах, подобных OS/2, Dos и в различных разновидностях MS-Windows, ваша программа видит
\nкак один символ\cJ, но что хранится в текстовых файлах является двумя символами\cM\cJ. Это означает, что, если вы не используете binmode() в этих системах, последовательности\cM\cJна диске будут преобразованы в\nна вводе и любые\nвашей программы будут преобразованы обратно в\cM\cJна выводе. Это то что вам нужно для текстовых файлов, но это может быть катастрофическим для двоичных файлов.Другим следствием использования binmode() (на некоторых системах) является то, что специальные маркеры конца файла будут рассматриваться как часть потока данных. Для систем из семейства Microsoft это означает, что, если бинарные данные содержат
\cZи вы не используете binmode(), то подсистема ввода-вывода эту последовательность принимает за конец файла.binmode() имеет важное значение не только для операций readline() и print(), но так же при использовании read(), seak(), sysread(), syswrite() и tell() (см. perlport для более подробной информации). См. переменные
$/и$\в perlvar о том, как вручную установить последовательности завершения строки для ввода и вывода.