我很好奇是否可以使用Storable的store_fd和fd_retrieve将数据结构存储到程序自己的数据文件句柄中,我意识到这不是最佳实践,我只是好奇它是否有效,我的快速尝试似乎不起作用。
发布于 2010-02-06 08:14:13
我不知道你为什么要这么做,但你可以假装。不过,您应该尽量避免这种情况。
为了方便起见,您可以打开一个文件句柄,读取$0中的代码行并将它们打印出来,直到您到达__DATA__,然后添加新的__DATA__部分。然后,技巧是将您的新文件重命名为$0,如果您的系统在程序运行时锁定了该文件,则可以通过exec将其重命名:
#!perl
my $mode = (stat($0))[2] & 07777;
open my($fh), '<', $0 or die "I can't open me! $!\n";
open my($new), '>', "$0.new" or die "I can't open you! $!\n";
eval { chmod( $mode, $new ) } or warn "Couldn't set permissions: $@\n";
while( <$fh> )
{
last if /^__DATA__$/;
print { $new } $_;
}
print "I am $$\n";
print { $new } "__DATA__\n", join '|', $$, time, (stat($0))[1];
rename( "$0.new", $0 )
__DATA__
64574|1265415126|8843292发布于 2010-02-06 05:13:31
DATA是用于读取存储在脚本中的数据的句柄。Conway的Inline::Files是我所知道的唯一一个谈论可写虚拟文件的模块。由于脚本文件通常是ASCII格式的,我不知道如果在MSDOS上得到二进制26字节,或者在UNIX上得到二进制4,在Storable的输出中会发生什么。
但是,如果您正在谈论通过在其中键入数据来存储数据,只是为了从脚本中读取数据,那么二进制问题仍然面临着您。
因此,最好使用YAML或JSON来实现持久性。我知道当从数据中检索数据时,YAML将会处理这个问题。
发布于 2016-02-07 00:27:55
我想出了我自己的解决方案。我并不是特别推荐它或其他任何脚本;在我的例子中,它是一个单元测试脚本,其中引用了多维散列结构中的值。我不会深入讨论这件事的用途和原因的技术细节,但最终的结果是,代码中的一个小修复或更改可能导致许多值需要更新(在验证更改有效之后)。
因此,我使用Data::Dumper将散列转移到__DATA__部分。将其写入文件句柄的代码如下所示:
use Data::Dumper;
$Data::Dumper::Terse = 1; # to Eval whole thing as a hash
$Data::Dumper::Indent = 1; # Looks better, just a preference
$Data::Dumper::Sortkeys = 1; # To keep changes minimal in source control
print $fh Dumper(\%HASH);在脚本开始时,我在存储了对初始句柄位置和mtime的引用后,从DATA加载散列(mtime用于确保文件在脚本执行期间没有被修改)。
use vars qw(%HASH $FILEPOS $MTIME);
{
$FILEPOS = tell(DATA);
$MTIME = (stat(DATA))[9];
local $/;
my $data = <DATA>;
%HASH = %{eval $data};
}最后,为了更新__DATA__部分,我在$FILEPOS上打开__FILE__,截断它并写入它。我简化了本例的错误处理。
open(my $fh, '>>', __FILE__) or die $!;
seek($fh, $FILEPOS, 0) or die $!;
die "File changed" if ((stat($fh))[9] != $MTIME);
truncate($fh, $FILEPOS) or die $!;
# Assumes Dumper is already loaded and configured as in first code snippet
print $fh Dumper(\%HASH);在开发过程中,一定要保留文件的备份,因为一个错误就会破坏所有的代码!
还要注意的是,这同样适用于Storable;存储将更高效、更快。唯一需要注意的是,它是二进制的,这意味着文件差异很可能不会出现在源代码控制中,而且它也不像Dumper的输出那样容易编辑。
https://stackoverflow.com/questions/2210081
复制相似问题