Чтение онлайн

на главную

Жанры

Язык программирования Perl

Шохирев Михаил Васильевич

Шрифт:

open(my $fh, ">$file") or die("Ошибка открытия: $!");

binmode($fh);

Запись двоичных данных или данных фиксированной длины может выполняться с помощью функции print($fh $record). Также имеется функция небуферизованного вывода syswrite, которой при вызове указываются три аргумента: файловый манипулятор, скалярная переменная с выводимыми данными и размер записываемого блока данных. Эта функция возвращает число фактически записанных байт (в случае ошибки syswrite возвращает undef), что можно использовать для проверки успешности записи. Это делается так:

syswrite($fh, $record, length($record)) == length($record)

or die("Ошибка
записи: $!");

Преобразование данных к двоичному виду производит функция 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)".

$record = pack 'l1 d1', time, rand; #

Вот еще несколько несложных примеров использования разных шаблонов для функции pack:

$bin = pack('a5', 'Yes'); # в $bin будет: 'Yes\0\0'

$bin = pack('A5', 'Yes'); # в $bin будет: 'Yes '

$bin = pack('a4', 'abcd','x','y','z'); # в $bin: 'abcd'

$bin = pack('aaaa', 'abcd','x','y','z'); # в $bin: 'axyz'

$bin = pack('C2', 65,66,67); # в $bin будет: 'AB'

$bin = pack('U2', 0x263A, 0x263B); # в $bin будет: '??'

$bin = pack ('cxxc', 65,66); # в $bin будет: 'A\0\0B'

Для преобразования данных из двоичного вида применяется функция unpack, которая распаковывает из скалярной переменной в список или массив значения двоичных данных в соответствии с указанным шаблоном.

@list_of_values = unpack($template, $binary_record);

Кроме того, с помощью функции unpack можно из строки извлекать подстроки фиксированной длины. Например, так можно извлечь из записи файла поля определенной длины в переменные:

# Поля данных в записи файла:

# c 1 по 7 байт - номер телефона

# с 8 длиной 30 - фамилия, имя, отчество абонента

# с 38 длиной 25 - адрес

# 1234567Бендер Остап Ибрагимович РСФСР, Черноморск

($phone, $name, $address)= unpack('A7A30A25', $record);

Чтобы пропустить ненужные поля, достаточно указать в шаблоне пропуск определенного количества байтов. Например, так можно не извлекать поле с телефонным номером:

($name, $address)= unpack('x7A30A25', $record);

Подробное описание шаблонов и работы функций pack и unpack можно найти в стандартной документации с помощью все той же утилиты чтения документации:

perldoc perlpacktut

Для чтения двоичных данных или текстовых данных фиксированной длины применяется функция read, которой в качестве аргументов передаются файловый манипулятор, скалярная переменная для вводимых данных и размер считываемого блока данных. Вот так, например, выглядит типичный цикл чтения двоичных данных:

until(eof($fh)) { # читать до достижения конца файла

# считать очередной блок данных и проверить его длину

read($fh, $record, $record_size) == $record_size

or die('Неправильная длина данных');

# распаковать данные по шаблону из $record в @data

@data = unpack($template, $record);

# обработать введенные данные...

}

При работе с данными фиксированной длины обычной практикой является считывание или запись данных в произвольном месте файла, например, при изменении только что считанного блока данных. Для этого нужно позиционировать позицию чтения или записи. Это делается с помощью функции seek, которой передается три аргумента: файловый манипулятор, смещение в байтах и указатель позиции отсчета. Позиция отсчета задается числами: 0 - от начала файла, 1 - от текущей позиции, 2 - от конца файла. Например:

seek($handle, 64, 0); # переместиться на 64 байта от начала

seek($handle, 25, 1); # сместиться на 25 байт вперед

seek($handle, -10, 2); # установиться на 10 байт до конца

seek($handle, 0, 0); # установить позицию в начало файла

С помощью функции tell, которая возвращает смещение относительно начала файла, можно узнать текущую позицию чтения-записи и использовать ее для дальнейших перемещений по файлу.

Поделиться:
Популярные книги

Черный Маг Императора 13

Герда Александр
13. Черный маг императора
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 13

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Маяк надежды

Кас Маркус
5. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Маяк надежды

Великий перелом

Ланцов Михаил Алексеевич
2. Фрунзе
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Великий перелом

Сопротивляйся мне

Вечная Ольга
3. Порочная власть
Любовные романы:
современные любовные романы
эро литература
6.00
рейтинг книги
Сопротивляйся мне

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Ох уж этот Мин Джин Хо 2

Кронос Александр
2. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 2

Энфис 6

Кронос Александр
6. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 6