【问题标题】:Print and save data in binary format in Perl在 Perl 中以二进制格式打印和保存数据
【发布时间】:2018-04-27 04:01:26
【问题描述】:

我的脚本生成了一些非常非常大的文件,我正在尝试以二进制格式打印/保存输出以尽可能减小文件大小!

该脚本每次生成五个值,例如:

$a1 = 1.64729
$a2 = 4.33329
$a3 = 3.55724
$a4 = 1.45759
$a5 = 7.474700

它在输出中打印如下:

A:1.64729,4.33329,3.55724,1.45759,7.474700

我不确定这是否是最好的方法,但我想在打印到输出时打包每一行!我在 Perl 中使用了 pack/unpack 内置函数!

我查看了 perldoc,但我不明白哪些格式说明符是正确的 (???)!

#!/usr/bin/perl

...

@A = ($a1,$a2,$a3,$a4,$a5);

print pack ("???", ("A:", join(",", map { sprintf "%.1f", $_ } @A)), "\n";

【问题讨论】:

  • 您最好只对整个文件使用压缩。您可以在编写时压缩它,并在必要时在阅读时解压缩它。 “非常非常大”到底有多大?
  • 1000个文件,每个压缩文件1.7G

标签: perl


【解决方案1】:

如果您压缩文件(而不是尝试写入二进制字节),您将得到一个小文件。那是因为您的整个文件将主要包含十位数字字符,加上一个小数点和一个逗号。

您可以在编写文件时通过IO::Zlib 压缩文件。这将使用 Zlib 库或 gzip 命令。

但是,如果您想使用pack,请继续。获取Camel Book,它提供了比标准 Perldoc 更清晰的文档。

这并不难:

my $output = "A:1.64729,4.33329,3.55724,1.45759,7.474700";
$output =~ s/^A://;                  #Remove the 'A:'
my @numbers = split /,/, $output     # Make into an array
my $packed =  pack "d5", @numbers;   # Pack five inputs as floating point numbers
say join ",", "d5", $packed;         # Unpacks those five decimal encoded numbers

您可能不得不使用syswritesysread,因为它们不会读写字符串。这是无缓冲的读取和写入,您必须指定正在读取或写入的字节数。

还有一件事:如果您知道小数点在数字中的位置(也就是说,它始终是 1 到 10 之间的数字),您可以将数字转换为整数,这样您就可以打包 将数字转换为更少的字节数:

my $output = "A:1.64729,4.33329,3.55724,1.45759,7.474700";
$output =~ s/^A://;                  #Remove the 'A:'
$output =~ s/,//g;                   #Remove all the decimal points
my @numbers = split /,/, $output     # Make into an array
my $packed =  pack "L5", @numbers;   # Pack five inputs as unsigned long numbers

【讨论】:

    猜你喜欢
    • 2011-07-12
    • 2016-04-06
    • 2018-08-30
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多