rak*_*van 5 perl loops bytearray
感谢大家提前.
我想访问二进制标量的第n个字节.例如,您可以在一个标量变量中获取所有文件数据...
想象一下,二进制数据被收集到标量中......
open(SOURCE, "<", "wl.jpg");
my $thisByteData = undef;
while(<SOURCE>){$thisByteData .= $_;}
close SOURCE;
Run Code Online (Sandbox Code Playgroud)
$ thisByteData是原始二进制数据.当我使用length($ thisByteData)时,我得到了字节数,所以Perl知道它有多大.我的问题是如何访问第N个字节?
旁注:我的函数将接收这个二进制标量,它在我的函数中,我想访问第N个字节.关于如何收集这些数据的帮助是值得赞赏的,但不是我正在寻找的.无论其他程序员想要收集二进制数据的方式取决于他们,我的工作是在传递给我时获取第N个字节:)
再次感谢所有人的帮助!
感谢@muteW让我比以往任何时候都更进一步.我想我不理解unpack(...)正确.
print(unpack("N1", $thisByteData));
print(unpack("x N1", $thisByteData));
print(unpack("x0 N1", $thisByteData));
Run Code Online (Sandbox Code Playgroud)
返回以下内容:
4292411360
3640647680
4292411360
Run Code Online (Sandbox Code Playgroud)
我假设这3行都会访问相同的(第一个)字节.不使用"x"只是"x"和"x $ pos"会产生意想不到的结果.
我也尝试过这个......
print(unpack("x0 N1", $thisByteData));
print(unpack("x1 N1", $thisByteData));
print(unpack("x2 N1", $thisByteData));
Run Code Online (Sandbox Code Playgroud)
返回...与上次测试相同...
4292411360
3640647680
4292411360
Run Code Online (Sandbox Code Playgroud)
我肯定错过了一些关于unpack如何工作的东西.
如果我这样做......
print(oct("0x". unpack("x0 H2", $thisByteData)));
print(oct("0x". unpack("x1 H2", $thisByteData)));
print(oct("0x". unpack("x2 H2", $thisByteData)));
Run Code Online (Sandbox Code Playgroud)
我得到了我所期待的......
255
216
255
Run Code Online (Sandbox Code Playgroud)
无需使用oct()就无法解压缩给我自己?
作为旁注:我认为在使用"x $ pos N1"时,我得到了这些字节整数的2的补码.我期待这些作为前3个字节.
255
216
255
Run Code Online (Sandbox Code Playgroud)
再次感谢所有人的帮助.
特别感谢@brian d foy和@muteW ...我现在知道如何使用unpack(...)访问我的二进制标量的第N个字节.我现在有一个新问题要解决,这与这个问题无关.再次感谢所有帮助人员!
这给了我想要的结果......
print(unpack("x0 C1", $thisByteData));
print(unpack("x1 C1", $thisByteData));
print(unpack("x2 C1", $thisByteData));
Run Code Online (Sandbox Code Playgroud)
unpack(...)有很多选项,所以我建议其他读取这个选项的人阅读pack/unpack文档以获得他们选择的字节数据结果.我也没有尝试使用@brian提到的Tie选项,我希望尽可能简化代码.
如果你有一个字符串中的数据,并且你想要获得某个字节,请使用substr,只要你将字符串视为字节开头即可.
但是,您可以直接从文件中读取它,而不是所有这些字符串无意义的人都在填补你的头脑.:)使用sysopen和正确的选项打开文件,使用seek将自己放在想要的位置,并阅读sysread所需的内容.
你跳过所有的东西,变通办法open,并readline试图为你做.如果您要关闭所有功能,请不要使用它们.
由于 $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
Run Code Online (Sandbox Code Playgroud)
通读包文档,了解可在模板中使用的参数来获取不同的返回值。
编辑 - 下面的评论表明您缺少第一个字节的高位 nybble ('f')。我不确定为什么会发生这种情况,但这是一种可行的替代方法,同时我将进一步研究 unpack 的行为。
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
Run Code Online (Sandbox Code Playgroud)
使用此命令,前四个字节的输出为 - 0xff 0xd8 0xff 0xe0,与文档相符。