2012-04-06 53 views
2

我正在嘗試從大於12 GB的Berkeley DB文件中讀取數據並將其寫入到鍵值對中的文本文件中。 但是我無法這樣做,因爲我的過程在閱讀2600萬條記錄後停止。 我試着用perl/ruby​​讀取文件,但是看起來記錄的對象只能容納2600萬條記錄。 有什麼方法可以分割BDB文件然後讀取記錄?或者,如果我能找到某種方式來讀取塊中的數據,然後處理它們?無法從大型Berkeley DB文件讀取數據

+1

如果你顯示你的代碼,也許有人可以幫你修復它。 – 2012-04-06 21:25:20

回答

0

沒有看到你的代碼很少有人說。你在使用BerkeleyDB模塊嗎?該文件是否爲散列表的形式?你用Perl和Java標記了你的問題;你試過用Java和Perl以及Ruby來閱讀文件嗎?

您可能已經使用Perl命中虛擬內存限制,因爲散列和標量值的支持數據與C等簡單字符串相比是巨大的。

如果拆分伯克利DB文件的方式,但要求是簡單,可以寫在只有幾行C.

請出示你的Perl代碼,如果你想用它幫助我懷疑,或者用C或Java重寫它。一旦數據作爲鍵/值對存儲在文本文件中,Perl可以輕鬆處理。


編輯

我建議你使用由DB_File模塊提供的本地伯克利DB API。這將避免將所有數據保存在單個Perl哈希中,並可能解決您的問題。

此代碼編譯但僅在最小數據上測試,因爲我顯然無法訪問您的數據庫文件。

use strict; 
use warnings; 

use DB_File; 

my $db = tie my %dbhash, 'DB_File', 'TestId', O_RDONLY, 0644, $DB_BTREE 
    or die "Cannot open file 'TestId' :$!\n"; 

my $file = 0; 
my $fh; 
my $c = 0; 

my ($key, $val); 

my $stat = $db->seq($key, $val, R_FIRST); 
while ($stat == 0) { 

    if (not $fh or $c == 10_000_000) { 
    $file++; 
    open $fh, '>', "TestId$file.txt" or die $!; 
    $c = 0; 
    } 

    print $fh "$key|$val\n"; 
    $c++; 
} 
continue { 
    $stat = $db->seq($key, $val, R_NEXT); 
} 
close $fh or die $!; 

undef $db; 
untie %dbhash; 

編輯2

如果方法使用DB_File有同樣的問題,那麼我建議你試試BerkeleyDB模塊來代替。它由同一個作者編寫,但有一個看起來獨立於Perl哈希的接口。

這是我以前嘗試使用替代模塊的等效代碼。它在最小數據集上運行良好。如果這也失敗了,那麼我建議你將一行刪除到模塊的作者Paul Marquess

use strict; 
use warnings; 

use BerkeleyDB; 

my $db = BerkeleyDB::Btree->new(-Filename => 'TestId') 
    or die "Cannot open file 'TestId' :$!\n"; 

my $cursor = $db->db_cursor; 

my $file = 0; 
my $fh; 
my $c = 0; 

my $key = my $val = ""; 

my $stat = $cursor->c_get($key, $val, DB_FIRST); 
while ($stat == 0) { 

    if (not $fh or $c == 10_000_000) { 
    $file++; 
    open $fh, '>', "TestId$file.txt" or die $!; 
    $c = 0; 
    } 

    print $fh "$key|$val\n"; 
    $c++; 
} 
continue { 
    $stat = $cursor->c_get($key, $val, DB_NEXT); 
} 

close $fh or die $!; 
+0

你知道我怎麼能用java做同樣的事嗎? – vikknp 2012-04-09 21:41:23

+0

我不熟悉Berkely DB的Java庫,但我相信你的問題可以通過使用Perl DB_File模塊提供的本地API來解決。我已經添加到我的答案來演示。 – Borodin 2012-04-10 04:40:57

+0

這沒有幫助。它再次創造了3個文件2,其中有1000萬條記錄,最後是600萬條記錄。所以它似乎仍然保持數據在一個散列。 my $ db = tie my%dbhash,'DB_File','TestId',O_RDONLY,0644,$ DB_BTREE or die「Can not open file'TestId':$!\ n」; – vikknp 2012-04-10 06:24:30