我是 Perl 新手。 我正在编写一些代码来从键查找数据库中的值。 如果我对键和值的 %hash 进行循环:我可以看到我的键和值。 但是,当我想加载特定键时,该值是空的。
$database_obj = tie(%db_hash, 'DB_File', $database_name,
O_RDONLY, 0644, $DB_HASH) ||
fatal_exit "Cannot open database %s: $!", $database_name;
# This work - Console display [myKey1]: {myVal1} ...
while (my ($key, $val) = each(%db_hash))
{ print "[$key]: {$val}\n"; }
# but, this doesn't work - $value is empty - I want to get myVal1
$value = $db_hash{myKey1};
db_dump 显示此标头:
VERSION=3
format=bytevalue
type=hash
h_nelem=4098
db_pagesize=4096
HEADER=END
如果有人可以帮助我吗?提前致谢。 问候, 雅尼克
我尝试操作带或不带引号的密钥格式。
附加测试1
#!/usr/bin/perl
use strict;
use warnings;
use DB_File;
use Fcntl;
use Sys::Syslog qw(:DEFAULT setlogsock);
my ($database_obj, %db_hash);
my $database_name="./mydb.db";
$database_obj = tie(%db_hash, 'DB_File', $database_name,
O_RDONLY, 0644, $DB_HASH) ||
print "Cannot open database %s: $!", $database_name;
print "DUMP ...\n";
while (my ($key, $val) = each(%db_hash))
{ print "[$key]: {$val}\n"; }
my $search="mykey.1";
print "ONLY $search\n";
my $value = $db_hash{$search};
print "Value: $value\n" unless $value;
结果:
DUMP ...
[mykey.1]: {myVal1;myVal-1}
[mykey.2]: {myval2}
ONLY mykey.1
Use of uninitialized value $value in concatenation (.) or string at test.pl line 25.
Value:
键和值可以包含 . -> 这似乎是一个问题?
附加测试2
#!/usr/bin/perl
use strict;
use warnings;
use DB_File;
use Fcntl;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Data::Dumper;
$Data::Dumper::Useqq=1;
my ($database_obj, %db_hash);
my $database_name="./mydb.db";
$database_obj = tie(%db_hash, 'DB_File', $database_name,
O_RDONLY, 0644, $DB_HASH) ||
print "Cannot open database %s: $!", $database_name;
#print "DUMP ...\n";
# while (my ($key, $val) = each(%db_hash))
# { print "[$key]: {$val}\n"; }
print Dumper \%db_hash;
my $search="mykey.1";
print "ONLY $search\n";
my $value = $db_hash{"$search"};
print "Value: $value\n" unless $value;
结果:
$VAR1 = {
"mykey.1\0" => "myVal1;myVal-1\0",
"mykey.2\0" => "myval2\0"
};
抱歉耽搁了,看来我们不在同一个时区。 数据用 postmap 填充
我看到我的字符串以(空终止符?)结尾,因此我尝试将其添加到查找中。
#!/usr/bin/perl
use strict;
use warnings;
use DB_File;
use Fcntl;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Data::Dumper;
$Data::Dumper::Useqq=1;
my ($database_obj, %db_hash);
my $database_name="./mydb.db";
$database_obj = tie(%db_hash, 'DB_File', $database_name,
O_RDONLY, 0644, $DB_HASH) ||
print "Cannot open database %s: $!", $database_name;
#print "DUMP ...\n";
# while (my ($key, $val) = each(%db_hash))
# { print "[$key]: {$val}\n"; }
print Dumper \%db_hash;
my $search="mykey.1\0";
print "ONLY $search\n";
my $value = $db_hash{"$search"};
print "Value: $value\n" unless $value;
结果:
$VAR1 = {
"mykey.1\0" => "myVal1;myVal-1\0",
"mykey.2\0" => "myval2\0"
};
ONLY mykey.1
没有返回值,因此 $value 似乎为空。
附加信息
@clamp 如果我删除“除非 $value”,它就可以工作。 我需要在密钥末尾添加!
在我最初的问题中提到,我正在使用 postmap 来生成数据库文件。
正如这里提到的:https://metacpan.org/pod/DB_File#An-Example-the-NULL-termination-problem。 C 程序在字符串(键和值)末尾添加 NULL 终止符。 Postmap 是用 C 编写的,因此添加了 NULL 终止符。
所以,我的问题是由于我需要使用 perl 读取由 C 程序生成的数据库
为了能够正确匹配密钥,需要在密钥末尾添加“ ”
$db_hash{"$search\0"}
而不是
$db_hash{"$search"}