В Perl действительно ли уместно использовать строку в качестве массива байтов, содержащего 8-разрядные данные? Вся документация я могу найти на этом предмете внимание на 7-разрядные строки.
Например, если я считал некоторые данные с двоичного файла в $data
my $data;
open FILE, "<", $filepath;
binmode FILE;
read FILE $data 1024;
и я хочу вывести первый байт, substr($data,1,1)
соответствующий? (снова, принятие его является 8-разрядными данными),
Я происхожу из главным образом C фон, и я привык передавать a char
указатель на a read()
функция. Моя проблема могла бы состоять в том, что я не понимаю то, что базовое представление строки находится в Perl.
В прилагаемой документации для команды read
, воспроизведенной здесь, содержится много информации, имеющей отношение к вашему вопросу.
read FILEHANDLE,SCALAR,LENGTH,OFFSET
read FILEHANDLE,SCALAR,LENGTH
Попытка прочитать LENGTH символов данных в переменную SCALAR из указанного файла FILEHANDLE. Возвращает количество символов, 0 в конце файла, или undef, если была произошла ошибка (в последнем случае также устанавливается $!). SCALAR будет увеличиваться или уменьшаться так, чтобы последний фактически прочитанный символ был последний символ скаляра после чтения.
Может быть задан OFFSET, чтобы поместить считанные данные в какое-либо место в строке, отличном от начала. Отрицательное значение OFFSET определяет размещение на столько символов, считая назад от конца строки. Положительное значение OFFSET больше, чем длины SCALAR, приводит к тому, что строка заполняется до требуемого требуемого размера на "\0" байт перед добавлением результата чтения. добавляется.
Этот вызов фактически реализован в терминах либо Perl, либо системного вызова fread(). Чтобы получить настоящий системный вызов read(2), см. "sysread".
Обратите внимание на символы: в зависимости от состояния файлового хэндла, считываются либо (8-битные) байты, либо символы. По умолчанию все файловые ручки работают с байтами, но, например, если файловая ручка был открыт с помощью уровня ввода/вывода ":utf8" (см. "open", и прагма прагма "open", open), ввод/вывод будет работать с кодированными в UTF-8 символами Юникода, а не байтами. Аналогично для ":encoding" прагма: в этом случае могут быть прочитаны практически любые символы.
См. perldoc -f pack и perldoc -f unpack о том, как рассматривать строки как байтовые массивы.
Если вы расскажете нам, что вы пытаетесь сделать с байтовым массивом, это может помочь. Есть разные способы работы с двоичными данными, и для каждого из них используется свой набор инструментов.
Вы хотите преобразовать данные в массив Perl? Если это так, то хорошим началом будут pack
и unpack
. split
также может пригодиться.
Хотите получить доступ к отдельным элементам строки, не распаковывая ее? Если это так, то substr
работает быстро и работает с 8-байтовыми данными. Если вам нужна другая битовая глубина, обратите внимание на функцию vec
, которая обрабатывает строку как битовый вектор.
Вы хотите просканировать строку и преобразовать одни байты в другие? Тогда могут быть полезны конструкции s ///
или tr ///
.
Вы, вероятно, захотите использовать sysopen и sysread , если хотите читать байты из двоичного файла.
См. Также perlopentut .
Уместно это или необходимо, зависит от того, что именно вы пытаетесь сделать.
#!/usr/bin/perl -l
use strict; use warnings;
use autodie;
use Fcntl;
sysopen my $bin, 'test.png', O_RDONLY;
sysread $bin, my $header, 4;
print map { sprintf '%02x', ord($_) } split //, $header;
Вывод:
C:\Temp> t 89504e47