2014-10-30 51 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