【发布时间】:2019-08-02 13:35:23
【问题描述】:
我正在使用 Perl(5.8.8,不要问),我正在查看一个序列化的二进制文件,我想从中解析和窃取信息。
格式如下:
- 7个字节,不知什么意思(DB DB 00 00 7A 03 00)
- 空 (0x00)
- 带有用户ID的7字节字符串
- 空 (0x00)
- 要丢弃的 12 字节字符串
- 空 (0x00)
- 3 字节数字指定要遵循的项目数
- 空 (0x00)
- 第一项的可变长度字符串
- 换行符 (0x0a)
- 第二个项目的可变长度字符串
- 换行符 (0x0a)
- 等等...
- 空 (0x00)
- 带有用户ID的7字节字符串
- 等等...
我当前的代码有点天真地跳过了前 8 个字节,然后逐字节读取,直到它达到空值,然后进行非常具体的解析。
sub readGroupsFile {
my %index;
open (my $fh, "<:raw", "groupsfile");
seek($fh, 8, 0);
while (read($fh, my $userID, 7)) {
$index{$userID} = ();
seek($fh, 18, 1);
my $groups = "";
while (read($fh, my $byte, 1)) {
last if (ord($byte) == 0);
$groups .= $byte;
}
my @grouplist = split("\n", $groups);
$index{$userID} = \@grouplist;
}
close($fh);
return \%index;
}
好消息?它有效。
但是,我认为它不是很优雅,想知道是否可以使用指定要遵循的项目数量的 2 字节数字来加快解析速度。我不知道为什么它会在那里。
我认为unpack() 及其模板可能会提供答案,但我无法弄清楚它如何处理具有自己可变长度的字符串的可变长度数组。
【问题讨论】:
-
你为什么要找18?根据您提供的数据,它似乎应该是 20:0x0 + 15 字节 str + 0x0 + 2 字节 + 0x0 = 20
-
我认为问题在于
unpack需要一个字符串来解压,它不能直接从文件中读取。因此,您需要先将文件读入字符串,但这与您所拥有的相比可能效率不高 -
抱歉,它实际上是一个12字节的字符串,数字可能是3字节。 +3 nulls 是 18。我算错了。但真正的问题在于它后面的数组。我已经调整了帖子。
-
一旦你进入“可变长度字符串”项目可以切换到
readline(又名<>),因为它们都以换行符结尾。我认为没有理由不能混合read和<>(只是不是sysread,它是无缓冲的)。 -
我不明白“可变长度数组”有什么问题......你不知道有多少个“可变长度字符串 i>”有吗?一旦你切换到
readline,你就可以测试你读到的每一行是否有一个以null结尾的7字节字符串;根据描述,似乎没有“项目”可以那样。