Устанавливает дескриптор 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 о том, как вручную установить
последовательности завершения строки для ввода и вывода.