Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中,可以将字符串视为字节数组吗?_Perl_String_Binary - Fatal编程技术网

在Perl中,可以将字符串视为字节数组吗?

在Perl中,可以将字符串视为字节数组吗?,perl,string,binary,Perl,String,Binary,在Perl中,使用字符串作为包含8位数据的字节数组是否合适?我能找到的关于这个主题的所有文档都集中在7位字符串上 例如,如果我将一些数据从二进制文件读入$data my $data; open FILE, "<", $filepath; binmode FILE; read FILE $data 1024; my$data; 打开文件,“您可能想使用,如果您想从二进制文件中读取字节 另见 这是适当的还是必要的取决于你到底想做什么 #!/usr/bin/perl -l use stri

在Perl中,使用字符串作为包含8位数据的字节数组是否合适?我能找到的关于这个主题的所有文档都集中在7位字符串上

例如,如果我将一些数据从二进制文件读入
$data

my $data;

open FILE, "<", $filepath;
binmode FILE;
read FILE $data 1024;
my$data;
打开文件,“您可能想使用,如果您想从二进制文件中读取字节

另见

这是适当的还是必要的取决于你到底想做什么

#!/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 C:\Temp>t
89504e47此处复制的
read
命令的捆绑文档提供了许多与您的问题相关的信息

读取文件句柄、标量、长度、偏移量

读取文件句柄,标量,长度

尝试将数据的长度字符读入变量标量 从指定的文件句柄。返回 实际读取的字符,文件末尾为0,如果有,则为未定义字符 是一个错误(在后一种情况下,还设置了$!)。标量将 放大或缩小,使最后一个实际读取的字符 读取后标量的最后一个字符

可以指定偏移量以将读取的数据放置在某个位置 在字符串中,而不是在开头。负偏移量 指定向后计数的多个字符的位置 从字符串末尾开始。大于 标量的长度导致字符串填充到 读取结果之前所需的大小为“\0”字节 附加

该调用实际上是根据Perl或 系统的fread()调用。要获得真正的读取(2)系统调用,请参阅 “系统读取”

注意字符:根据文件句柄的状态, 读取(8位)字节或字符。默认情况下为所有 filehandles对字节进行操作,但例如,如果filehandle 已使用“:utf8”I/O层打开(请参阅“打开”,并且 “打开”pragma,open),I/O将在UTF-8编码上运行 Unicode字符,而不是字节。与“:编码”类似 pragma:在这种情况下,几乎可以读取任何字符


有关如何将字符串视为字节数组的信息,请参见和。

如果您告诉我们如何使用字节数组,可能会有更多帮助。处理二进制数据有多种方法,每种方法都适用于不同的工具集

是否要将数据转换为Perl数组?如果是这样,
pack
unpack
是一个很好的开始。
split
也可以派上用场

是否要在不解压缩的情况下访问字符串的各个元素?如果是这样,
substr
速度很快,可以处理8字节数据。如果需要其他位深度,请查看
vec
函数,该函数将字符串作为位向量处理


您想扫描字符串并将某些字节转换为其他字节吗?然后
s//
tr//
结构可能会有用。

请允许我发布一个关于将字符串视为二进制数组的小示例,因为我自己发现很难相信称为“substr”的东西“将处理空字节;但看起来确实如此-下面是perl调试器终端会话的一个片段(使用字符串和数组/列表方法):

$perl-d
从perl5db.pl版本1.32加载数据库例程
编辑器支持可用。
输入h或“h”以获取帮助,或输入“man perldebug”以获取更多帮助。
^D
已调试程序已终止。使用q退出,或使用R重新启动,
使用o inhibit_exit避免程序终止后停止,
h q、h R或h o以获取其他信息。
DB$str=“\x00\x00\x84\x00”
DB打印$str
�
DB print unpack(“H*”,$str)#通过“unpack”将$str的内容显示为十六进制`
00008400
DB$str2=substr($str,2,2)
DB打印解包(“H*”,$str2)
8400
DB$str2=substr($str,1,3)
DB打印解包(“H*”,$str2)
008400
[...]
DB@stra=分割(“”,$str);打印@stra#将字符串转换为数组(在空字符串处拆分)
�
DB打印解包(“H*”,$stra[3])#独立打印。元素。数组的十六进制形式
00
DB打印解包(“H*”,$stra[2])
84
DB打印解包(“H*”,$stra[1])
00
DB打印解包(“H*”,$stra[0])
00
DB print unpack(“H*”,join(“”,@stra[1..3])#通过索引只打印数组/列表的一部分(使用触发器[两点]操作符)
008400
字符串是大于一个字节的“字符”字符串。您可以将字节存储在它们中,并像处理字符一样对它们进行操作,获取它们的
substr
s等等,只要您只是在处理内存中的实体,一切都非常美好。数据存储很奇怪,但这绝不是你的问题

当您尝试读取和写入文件时,字符可能不会映射到字节这一事实变得非常重要和有趣。更不用说烦人了。Perl试图在常见情况下执行您想要的操作,这实际上会使这种烦恼变得更糟:如果字符串中的所有字符都适合一个字节,而您恰好在非Windows操作系统上,那么您实际上不必执行任何特殊的读写字节操作。然而,如果您存储了一个非字节大小的字符,并试图编写它,而没有给出如何处理它的线索,Perl就会抱怨

这有点离题了,主要是因为编码是一个大而混乱的话题。让我在这里留下一些参考资料:看看、、和,有很多搞笑和血腥的细节

因此,总结答案是“是的,如果字符串实际上包含字节,那么可以将字符串视为包含字节,而这只能通过读取和写入字节来保证。”

:或迂腐地说,“虽然它可以表示比字节更大的值范围
$ perl -d

Loading DB routines from perl5db.pl version 1.32
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

^D
Debugged program terminated.  Use q to quit or R to restart,
  use o inhibit_exit to avoid stopping after program termination,
  h q, h R or h o to get additional info.  

  DB<1> $str="\x00\x00\x84\x00"

  DB<2> print $str
�
  DB<3> print unpack("H*",$str) # show content of $str as hex via `unpack`
00008400
  DB<4> $str2=substr($str,2,2)

  DB<5> print unpack("H*",$str2)
8400
  DB<6> $str2=substr($str,1,3)

  DB<7> print unpack("H*",$str2)
008400

[...]

  DB<30> @stra=split('',$str); print @stra # convert string to array (by splitting at empty string)
�
  DB<31> print unpack("H*",$stra[3]) # print indiv. elems. of array as hex
00
  DB<32> print unpack("H*",$stra[2]) 
84
  DB<33> print unpack("H*",$stra[1]) 
00
  DB<34> print unpack("H*",$stra[0]) 
00
  DB<35> print unpack("H*",join('',@stra[1..3])) # print only portion of array/list via indexes (using flipflop [two dots] operator) 
008400
use Devel::Peek;

my $x = "bluh bluh bluh bluh";
Dump($x);
$x =~ /bluh/mg;
Dump($x);
$x =~ /bluh/mg;
Dump($x);