2014-10-30 74 views
0

我的脚本生成一些非常非常大的文件,我试图以二进制格式打印/保存输出以尽可能减小文件大小!以perl格式打印和保存二进制格式的数据

每个脚本生成5个值,如时间:

$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"; 
+0

您可能最好在整个文件上使用压缩。您可以在写入时对其进行压缩,并在必要时对其进行解压缩。 “非常非常大”有多大? – ysth 2014-10-30 22:25:15

+0

1000个文件,每个压缩文件1.7 G – EpiMan 2014-10-30 22:28:31

回答

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 
+0

谢谢,非常有帮助! :) – EpiMan 2014-10-31 00:58:59