首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Storable可以存储到数据文件句柄吗?

Storable可以存储到数据文件句柄吗?
EN

Stack Overflow用户
提问于 2010-02-06 04:10:20
回答 3查看 788关注 0票数 3

我很好奇是否可以使用Storable的store_fd和fd_retrieve将数据结构存储到程序自己的数据文件句柄中,我意识到这不是最佳实践,我只是好奇它是否有效,我的快速尝试似乎不起作用。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-02-06 08:14:13

我不知道你为什么要这么做,但你可以假装。不过,您应该尽量避免这种情况。

为了方便起见,您可以打开一个文件句柄,读取$0中的代码行并将它们打印出来,直到您到达__DATA__,然后添加新的__DATA__部分。然后,技巧是将您的新文件重命名为$0,如果您的系统在程序运行时锁定了该文件,则可以通过exec将其重命名:

代码语言:javascript
复制
#!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
票数 2
EN

Stack Overflow用户

发布于 2010-02-06 05:13:31

DATA是用于读取存储在脚本中的数据的句柄。Conway的Inline::Files是我所知道的唯一一个谈论可写虚拟文件的模块。由于脚本文件通常是ASCII格式的,我不知道如果在MSDOS上得到二进制26字节,或者在UNIX上得到二进制4,在Storable的输出中会发生什么。

但是,如果您正在谈论通过在其中键入数据来存储数据,只是为了从脚本中读取数据,那么二进制问题仍然面临着您。

因此,最好使用YAMLJSON来实现持久性。我知道当从数据中检索数据时,YAML将会处理这个问题。

票数 1
EN

Stack Overflow用户

发布于 2016-02-07 00:27:55

我想出了我自己的解决方案。我并不是特别推荐它或其他任何脚本;在我的例子中,它是一个单元测试脚本,其中引用了多维散列结构中的值。我不会深入讨论这件事的用途和原因的技术细节,但最终的结果是,代码中的一个小修复或更改可能导致许多值需要更新(在验证更改有效之后)。

因此,我使用Data::Dumper将散列转移到__DATA__部分。将其写入文件句柄的代码如下所示:

代码语言:javascript
复制
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用于确保文件在脚本执行期间没有被修改)。

代码语言:javascript
复制
use vars qw(%HASH $FILEPOS $MTIME);

{
    $FILEPOS = tell(DATA);
    $MTIME = (stat(DATA))[9];
    local $/;
    my $data = <DATA>;
    %HASH = %{eval $data};
}

最后,为了更新__DATA__部分,我在$FILEPOS上打开__FILE__,截断它并写入它。我简化了本例的错误处理。

代码语言:javascript
复制
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的输出那样容易编辑。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2210081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档