高效读取、处理连续二进制文件

2024-09-29 01:35:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我有非常大的二进制文件,没有行和字段分隔符。目标是高效地将这些文件处理为制表符分隔的文件。在

文件的结构如下:

每个记录都是固定长度的,20字节。每个字段的长度不同,三个字段的长度分别为3、7和10字节。每个字段也表示不同的数据类型,字段1和2是int,3是char。在

处理这些文件的最有效方法是什么?我希望尽可能简单,使用Bash工具dd/odsed/awk,尽可能避免使用perl/python,除非性能差异非常大。在

下面是一个工作尝试,很慢。以上工具我是新手,请详细解释。在

binfile="binfile.BIN"

for (( i = 0 ; i <= 20000000 ; i += 20 ))
do
    field1=$( od "${binfile}" -An --skip-bytes"$((${i}))" --read-bytes=3 --format=dI )
    field2=$( od "${binfile}" -An --skip-bytes"$((${i}+3))" --read-bytes=7 --format=dI )
    field3=$( od "${binfile}" -An --skip-bytes"$((${i}+10))" --read-bytes=10 --format=c )

    echo - ${field1}'\t'${field2}'\t'${field3} >> output.tab
done

Tags: 文件工具anformatread字节bytes二进制
3条回答

从STDIN读取,输出到STDOUT,并执行错误检查:

#!/usr/bin/perl

use strict;
use warnings;

use constant BLOCK_SIZE => 20;

binmode STDIN;    

while (1) {
    my $rv = read(STDIN, my $buf, BLOCK_SIZE);
    die("Error: $!\n") if !defined($rv);
    last if !$rv;
    die("Error: Insufficient data\n") if $rv != BLOCK_SIZE;
    print(join("\t", unpack('a3 a7 a10', $buf)), "\n");
}

但我很肯定你会发现这比一次读更多的书要慢,所以我用以下方法:

^{pr2}$
fold -b -w 20 | cut  output-delimiter $'\t' -b 1-3,4-10,11-20

如果您的“cut”不支持输出分隔符,请尝试“gcut”(GNU cut)或考虑安装gnucoreutils。在

请告诉我们不同的解决方案(请尽快尝试)

open my $fh, '<:raw', shift;

local $" = "\t";

while ( read $fh, my $rec, 20 ) {
    my @f = unpack 'a3 a7 a10', $rec;
    print "@f\n";
}

相关问题 更多 >