没有看到您的代码就没什么好说的了。你在使用BerkeleyDB 模块吗?文件是哈希表的形式吗?你已经用 Perl 和 Java 标记了你的问题;您是否尝试过使用 Java 以及 Perl 和 Ruby 读取文件?
您可能在使用 Perl 时达到了虚拟内存限制,因为与 C 等中的简单字符串相比,散列和标量值的支持数据非常庞大。
我怀疑是否有拆分 Berkely DB 文件的方法,但要求很简单,只需几行 C 即可编写。
如果您需要帮助,请出示您的 Perl 代码,或者用 C 或 Java 重写它。一旦数据作为键/值对存储在文本文件中,Perl 就可以轻松处理它。
编辑
我建议您使用 DB_File 模块提供的原生 Berkely 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 $!;