我不确定描述这一点的最佳方式。
本质上,我正在尝试写入需要特定协议的缓冲区。我想要的前两个字节是“10000001”和“11111110”(逐位)。如何将这两个字节写入 Perl 中的文件句柄?
要将拼写出的二进制转换为实际字节,您需要带有or的pack函数(取决于您拥有位的顺序):B
b
print FILE pack('B*', '1000000111111110');
但是,如果字节是常量,最好将它们转换为十六进制值并将\x
转义与字符串文字一起使用:
print FILE "\x81\xFE";
怎么样
# open my $fh, ...
print $fh "\x81\xFE"; # 10000001 and 11111110
自 5.6.0 版(2000 年 3 月发布)以来,perl 已支持二进制文字,如perldata中所述:
数字文字以下列任何浮点或整数格式指定:
12345 12345.67 .23E-10 # a very small number 3.14_15_92 # a very important number 4_294_967_296 # underscore for legibility 0xff # hex 0xdead_beef # more hex 0377 # octal (only numbers, begins with 0) 0b011011 # binary
为了便于阅读,您可以在数字之间的数字文字中使用下划线(下划线)。例如,您可以按三位(如 Unix 样式的模式参数,如
0b110_100_100
)或四位(表示半字节,如0b1010_0110
)或其他组对二进制数字进行分组。
你可能会想写
print $fh 0b10000001, 0b11111110;
但输出将是
129254
因为 10000001₂ = 129₁₀ 和 11111110₂ = 254₁₀。
您需要文字值的特定表示,即两个无符号字节。为此,请使用pack
模板"C2"
,即八位字节乘以 2。添加下划线以提高可读性并将其包装在一个方便的子例程中
sub write_marker {
my($fh) = @_;
print $fh pack "C2", 0b1000_0001, 0b1111_1110;
}
作为一个快速演示,请考虑
binmode STDOUT or die "$0: binmode: $!\n"; # we'll send binary data
write_marker *STDOUT;
当运行为
$ ./marker-demo | od -t x1
输出是
0000000 81 铁 0000002
如果不熟悉,这里使用od实用程序用于演示目的,因为输出在我的系统编码中包含一个控制字符和 Þ(拉丁文小刺)。
上面的调用命令od以十六进制呈现其输入中的每个字节,这是marker-demo的输出。请注意,10000001₂ = 81₁₆ 和 11111110₂ = FE₁₆。左列中的数字是偏移量:特殊标记字节从偏移量零开始(即立即),并且正好有两个。