GDBM_File互操作性问题从较旧的32位Perl过渡到64位Perl

问题描述

我有一些我想与x86_64 Perl 5.28.0一起使用的旧32位(i686)版本的Perl(5.8.6)创建的GDBM文件,但是它不起作用。这是我的测试代码

use strict;
use warnings;
use GDBM_File;

my $dbmfile = "/path/to/gdbm_test_file";
my %DBM;

eval {
    my $ok = tie(%DBM,'GDBM_File',$dbmfile,&GDBM_WRCREAT,0664);
    die "Error: Bad status!\n" unless $ok;
};
die "Error: Could not open $dbmfile.\n" if $@;

foreach my $key (sort(keys(%DBM))) {
    print "$key :: $DBM{$key}\n";
}
untie %DBM;

如果我使用较旧的i686 Perl和$dbmfile指向同一i686 Perl最近创建的GDBM文件运行此代码,它将正确读取GDBM文件并打印出其内容

但是,如果我使用x86_64 Perl 5.28.0运行此代码,则它只是失败。没错完全没有输出

如果我使用x86_64 Perl 5.10.1运行此代码,则eval会收到“错误状态”错误,并且我得到Error: Could not open /path/to/gdbm_test_file.

如果我使用x86_64 Perl 5.28.0创建了一个 new GDBM文件,并尝试使用旧的i686 Perl进行读取,则i686 Perl将在read error上死于foreach线。

平台:CentOS 6.8

gdbm.i686和gdbm.x86_64软件包都已安装,并且版本相同:1.8.0-39

有什么建议吗?这不可能吗?

解决方法

鉴于您对32位gdbm数据库和64位gdbm数据库不兼容的评论,我将使用gdbm_dump实用程序的32位版本将数据库转储到平面文件中,然后将其提供给gdbm_load的64位版本以重新创建数据库,以便可以由64位perl gdbm库读取。

根据CentOS提供的软件包,您可能必须从源代码构建这些版本以获得合适的版本-我不熟悉。


或者,使用32位版本的perl编写一个快速工具,以读取32位gdbm数据库并将其转换为不会遇到相同问题的不同dbm,因此32位和64位程序可以使用相同的文件。

伪代码:

tie my %gdbm,'GDBM_File','olddb.gdbm',read-only options;
tie my %other,'Other_DBM','newdb.whatever',write/create options;
while (my ($key,$value) = each %gdbm) {
    $other{$key} = $value;
}
untie %gdbm;
untie %other;