Язык программирования Perl
Шрифт:
Запись двоичных данных или данных фиксированной длины может выполняться с помощью функции 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,
Вот еще несколько несложных примеров использования разных шаблонов для функции pack:
Для преобразования данных из двоичного вида применяется функция unpack, которая распаковывает из скалярной переменной в список или массив значения двоичных данных в соответствии с указанным шаблоном.
Кроме того, с помощью функции unpack можно из строки извлекать подстроки фиксированной длины. Например, так можно извлечь из записи файла поля определенной длины в переменные:
Чтобы пропустить ненужные поля, достаточно указать в шаблоне пропуск определенного количества байтов. Например, так можно не извлекать поле с телефонным номером:
Подробное описание шаблонов и работы функций pack и unpack можно найти в стандартной документации с помощью все той же утилиты чтения документации:
Для чтения двоичных данных или текстовых данных фиксированной длины применяется функция read, которой в качестве аргументов передаются файловый манипулятор, скалярная переменная для вводимых данных и размер считываемого блока данных. Вот так, например, выглядит типичный цикл чтения двоичных данных:
При работе с данными фиксированной длины обычной практикой является считывание или запись данных в произвольном месте файла, например, при изменении только что считанного блока данных. Для этого нужно позиционировать позицию чтения или записи. Это делается с помощью функции seek, которой передается три аргумента: файловый манипулятор, смещение в байтах и указатель позиции отсчета. Позиция отсчета задается числами: 0 - от начала файла, 1 - от текущей позиции, 2 - от конца файла. Например:
С помощью функции tell, которая возвращает смещение относительно начала файла, можно узнать текущую позицию чтения-записи и использовать ее для дальнейших перемещений по файлу.