Язык программирования Perl
Шрифт:
Задавая различные форматы преобразования, можно выводить данные в требуемом представлении или в виде колонок указанной ширины. Более тонкое управление выводимыми данными организуется средствами форматирования отчетов, которые будут изучены в следующей лекции.
В файле с исходным текстом программы на Perl может располагаться
Двоичные данные обычно хранятся в файлах без разделителей записей в блоках фиксированной длины. После открытия двоичного файла функцией open нужно установить режим обработки двоичных данных с помощью функции binmode.
Запись двоичных данных или данных фиксированной длины может выполняться с помощью функции print($fh $record). Также имеется функция небуферизованного вывода syswrite, которой при вызове указываются три аргумента: файловый манипулятор, скалярная переменная с выводимыми данными и размер записываемого блока данных. Эта функция возвращает число фактически записанных байт (в случае ошибки syswrite возвращает undef), что можно использовать для проверки успешности записи. Это делается так:
Преобразование данных к двоичному виду производит функция pack, которая упаковывает в скалярную переменную список значений в соответствии с указанным шаблоном. В шаблоне каждое преобразуемое поле обозначается с помощью латинской буквы. Полный перечень шаблонов преобразования для функций pack и unpack приводится в таблице 9.2. За каждым символом в шаблоне может следовать десятичное число, которое рассматривается как ширина преобразуемого поля. Поля в шаблоне могут разделяться пробелами для удобства чтения.
Таблица 9.2. Шаблоны упаковки и распаковки данных
Шаблон | Мнемоника | Описание преобразования |
---|---|---|
a | Arbitrary | произвольная последовательность байтов, дополненная нулевым байтом \0 |
A | ASCII | строка символов ASCII, дополненная пробелами |
b / B | Bit string | строка битов с возрастающим / убывающим порядком битов |
c / C | Character | однобайтовые символы со знаком / без знака |
f / d | Float / Double | число с плавающей точкой одинарной / двойной точности |
F | Float | число с плавающей точкой одинарной точности во внутреннем представлении (NV) |
D | long Double | длинное число с плавающей точкой двойной точности |
h / H | Hex string | шестнадцатеричная строка с младшим / старшим полубайтом (nybble) в начале |
i / I | Integer | целое (>=32
|
j / J | целое во внутреннем представлении со знаком (IV) / без знака (UV) | |
l / L | Long | длинное (32 бита) целое со знаком / без знака |
n / N | Network | беззнаковое короткое (16 битов) / длинное (32 бита) целое с сетевым порядком байтов (big endian) |
p / P | Pointer | указатель на строку, оканчивающуюся \0 / фиксированной длины |
q / Q | Quad | сверхдлинное (64 бита) целое число со знаком / без знака |
s / S | Short | короткое (16 битов) целое со знаком / без знака |
u | uuencoded | строка, кодированная по алгоритму uuencode |
U | Unicode | строка символов Unicode |
v / V | VAX | беззнаковое короткое (16 битов) / длинное (32 бита) целое с VAX-порядком байтов (little endian) |
w | целое, сжатое в соответствии с кодировкой BER | |
x | вставка \0 (pack) / пропуск байта по направлению вперед (unpack) | |
X | пропуск байта по направлению назад | |
Z | ASCIIZ | строка ASCIIZ (оканчивающаяся \0), дополненная \0 |
@ | заполнение \0 до указанной позиции |
Например, целочисленное значение, возвращаемое функцией time, и дробное значение, возвращаемое функцией rand, можно упаковать в переменную $record с помощью шаблона 'l1 d1', который означает: "одно длинное целое число (long) и одно число с плавающей точкой двойной точности (double)".
Вот еще несколько несложных примеров использования разных шаблонов для функции pack:
Для преобразования данных из двоичного вида применяется функция unpack, которая распаковывает из скалярной переменной в список или массив значения двоичных данных в соответствии с указанным шаблоном.
Кроме того, с помощью функции unpack можно из строки извлекать подстроки фиксированной длины. Например, так можно извлечь из записи файла поля определенной длины в переменные:
Чтобы пропустить ненужные поля, достаточно указать в шаблоне пропуск определенного количества байтов. Например, так можно не извлекать поле с телефонным номером: