Можно также использовать операторы обратной галочки ('), подобный Perl:
directoryListing = `ls /`
puts directoryListing # prints the contents of the root directory
Удобный, если Вам нужно что-то простое.
то, Какой метод Вы хотите использовать, зависит от точно, что Вы пытаетесь выполнить; проверьте документы на большее количество деталей о различных методах.
Поскольку у вас уже есть содержимое файла в $ thisByteData, вы можете использовать pack / unpack для доступа к n-му байту.
sub getNthByte {
my ($pos) = @_;
return unpack("x$pos b1", $thisByteData);
}
#x$pos - treats $pos bytes as null bytes(effectively skipping over them)
#b1 - returns the next byte as a bit string
Читать в документации пакета, чтобы получить представление о параметрах, которые можно использовать в шаблоне для получения различных возвращаемых значений.
РЕДАКТИРОВАТЬ - Ваш комментарий ниже показывает, что вам не хватает старшего полубайта ('f') первого байта. Я не уверен, почему это происходит, но вот альтернативный метод, который работает, а пока я более подробно изучу поведение распаковки.
sub getNthByte {
my ($pos) = @_;
return unpack("x[$pos]H2", $binData);
}
(my $hex = unpack("H*", $binData)) =~ s/(..)/$1 /g;
#To convert the entire data in one go
Используя это, вывод для первых четырех байтов - 0xff 0xd8 0xff 0xe0, который соответствует документации .
] Если у вас есть данные в строке и вы хотите перейти к определенному байту, используйте substr , пока вы обрабатываете строку как байты, с которых нужно начинать.
Однако вы можете читать это прямо из файла, без всей этой строковой ерунды, которой люди забивают вам голову. :) Откройте файл с помощью sysopen и правильных опций, используйте seek , чтобы попасть туда, куда хотите, и прочтите, что вам нужно, с помощью sysread .
Вы пропускаете все обходные пути для вещей, которые open
и readline
пытаются сделать за вас. Если вы просто собираетесь отключить все их функции, даже не используйте их.
Я думаю, что правильный ответ включает упаковку / распаковку, но это также может сработать:
use bytes;
while( $bytestring =~ /(.)/g ){
my $byte = $1;
...
}
«использовать байты» гарантирует, что вы никогда не увидите символы, но если у вас есть строка символов и обрабатывая его как байты, вы что-то делаете не так. Внутренняя кодировка символов Perl не определена, поэтому данные, которые вы видите в строке в разделе «использовать байты», почти бессмысленны.
Встроенная переменная Perl $ /
(или $ INPUT_RECORD_SEPARATOR
, если вы используете
ing English
) управляет идеей Perl о «линии». По умолчанию он установлен на "\ n"
, поэтому строки разделяются символами новой строки (да), но вы можете изменить это на любую другую строку. Или измените его на ссылку на число:
$/ = \1;
while(<FILE>) {
# read file
}
Установка его на ссылку на число сообщит Perl, что «строка» - это это количество байтов.
Итак, что именно вы пытаетесь сделать? Вероятно, есть несколько модулей, которые будут делать то, что вы пытаетесь сделать, и, возможно, более эффективно. Если вы просто пытаетесь научиться это делать, продолжайте, но если у вас есть конкретная задача, подумайте о том, чтобы не изобретать колесо (если вы этого не хотите).
РЕДАКТИРОВАТЬ: Спасибо jrockway в комментариях ...
Если у вас есть данные Unicode, они могут читать не один байт, а один символ, но если это произойдет, вы сможете использовать байты;
чтобы включить отключена автоматическая трансляция байтов в символы.
Теперь вы говорите, что хотите прочитать все данные сразу, а затем передать их функции. Давайте сделаем это:
my $data;
{
local $/;
$data = <FILE>;
}
Или это:
my $data = join("", <FILE>);
Или кто-то предложит модуль File :: Slurp
, но я думаю, что это немного излишне. Однако давайте превратим весь файл в массив байтов:
use bytes;
...
my @data = split(//, join("", <FILE>));
А затем у нас есть массив байтов, который мы можем передать функции. Нравится?
вы говорите, что хотите прочитать все данные сразу, а затем передать их функции. Давайте сделаем это:my $data;
{
local $/;
$data = <FILE>;
}
Или это:
my $data = join("", <FILE>);
Или кто-то предложит модуль File :: Slurp
, но я думаю, что это немного излишне. Однако давайте превратим весь файл в массив байтов:
use bytes;
...
my @data = split(//, join("", <FILE>));
А затем у нас есть массив байтов, который мы можем передать функции. Нравится?
вы говорите, что хотите прочитать все данные сразу, а затем передать их функции. Давайте сделаем это:my $data;
{
local $/;
$data = <FILE>;
}
Или это:
my $data = join("", <FILE>);
Или кто-то предложит модуль File :: Slurp
, но я думаю, что это немного излишне. Однако давайте превратим весь файл в массив байтов:
use bytes;
...
my @data = split(//, join("", <FILE>));
А затем у нас есть массив байтов, который мы можем передать функции. Нравится?
Не зная больше о том, что вы пытаетесь сделать со своими данными, что-то вроде этого будет перебирать байты в файле:
open(SOURCE, "wl.jpg");
my $byte;
while(read SOURCE, $byte, 1) {
# Do something with the contents of $byte
}
close SOURCE;
Будьте осторожны с объединением, используемым в вашем примере ; вы можете получить преобразование новой строки, что определенно не то, чего вы хотите при чтении двоичных файлов. (Также неэффективно постоянно расширять скаляр во время его чтения.) Это идиоматический способ преобразовать весь файл в скаляр Perl:
open(SOURCE, "<", "wl.jpg");
local $/ = undef;
my $big_binary_data = <SOURCE>;
close SOURCE;