java - 无法从大型 Berkeley DB 文件中读取数据

标签 java perl berkeley-db

我正在尝试从大小 > 12 GB 的 Berkeley DB 文件中读取数据,并以键值对的形式写入文本文件。 但我无法这样做,因为我的进程在读取 2600 万条记录后停止。 我尝试使用 perl/ruby 读取文件,但似乎获取记录的对象只能保存 2600 万条记录。 有什么方法可以拆分BDB文件然后读取记录吗?或者我是否可以找到某种方法来分块读取数据然后处理它们?

最佳答案

没有看到您的代码就没什么可说的了。你在使用 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 $!;

关于java - 无法从大型 Berkeley DB 文件中读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10047947/

相关文章:

java - 在屏幕外绘制二维图形?然后将其一部分并显示在屏幕上

regex - 使用 sed/perl 式正则表达式或 awk 展平嵌套列表模式

json - 用于同时请求的 perl Mojo 和 JSON

berkeley-db - 如何打开本地比特币数据库

java - "main"java.util.InputMismatchException 处出现异常?

java - 交替符号+循环

regex - 删除多行 C 样式/*注释*/使用 Perl 正则表达式

c - 伯克利数据库 : DB->compact() always fails for hash-based databases

java - 优化 BerkeleyDB JE 数据库

java - 如何从java代码调用Web服务?