在我的脚本中,我需要从磁盘文件加载一些信息,并且在脚本运行期间可能会更改信息。要保持文件在磁盘中的一致性,并且它在内存副本中我需要 只要在内存中更改信息或定期写入信息,就将信息写回磁盘 返回磁盘或在脚本退出时将其写回,这是首选的,因为它将节省大量IO时间并使脚本响应。
所以就像标题一样,我的问题是perl是否有一些能满足我需求的机制?
答案 0 :(得分:27)
我认为您正在寻找END
block:
END {
# cleanup
}
END代码块尽可能晚地执行,也就是说,在perl完成程序运行之后并且在退出解释器之前,即使它是由于die()函数退出。 (但是如果它通过exec变成另一个程序,或者被信号吹出水面 - 你必须自己陷阱(如果可以的话)。)你可能在文件中有多个END块 - 它们会以与定义相反的顺序执行;那就是:后进先出(LIFO)。使用-c开关运行perl时,或者编译失败时,不会执行END块。
答案 1 :(得分:9)
根据您的需求,有两种不同的方法可以做到这一点。
END
块。有关详细信息,请参阅上一个答案:)DESTROY
块/子。也就是说,如果您想将逻辑嵌入到模块或类中,则可以使用DESTROY
。看一下下面的例子(这是一个有效的例子,但是省略了错误检查等一些细节):
#!/usr/bin/env perl
package File::Persistent;
use strict;
use warnings;
use File::Slurp;
sub new {
my ($class, $opt) = @_;
$opt ||= {};
my $filename = $opt->{filename} || "./tmpfile";
my $self = {
_filename => $filename,
_content => "",
};
# Read in existing content
if (-s $filename) {
$self->{_content} = File::Slurp::read_file($filename);
}
bless $self, $class;
}
sub filename {
my ($self) = @_;
return $self->{_filename};
}
sub write {
my ($self, @lines) = @_;
$self->{_content} .= join("\n", @lines);
return;
}
sub DESTROY {
my ($self) = @_;
open my $file_handle, '>', $self->filename
or die "Couldn't save persistent storage: $!";
print $file_handle $self->{_content};
close $file_handle;
}
# Your script starts here...
package main;
my $file = File::Persistent->new();
$file->write("Some content\n");
# Time passes...
$file->write("Something else\n");
# Time passes...
$file->write("I should be done now\n");
# File will be written to only here..
答案 2 :(得分:1)
要处理Control-C,您需要处理信号(不触发END块)。下一步可以完成:
$SIG{INT} = \&signal_handler;
$SIG{TERM} = \&signal_handler;
sub signal_handler {
#implement here pre exit logic
die "\n";
}