[英]How can I open a file only if it is not already open, in Perl?
如果我有一個打開文件的子程序,那么只有在第一次調用subrountine時才能確保它打開它的最佳方法是什么? 我有這個但不確定它是否是最佳實踐:
{
my $count = 0;
sub log_msg {
my ($msg,$name) = @_;
if ($count == 0) {
my $log_file_name = "/tmp/" . $name;
open my $log_fh,">",$log_file_name or croak "couldn't open $log_file_name : $!";
print $log_fh "$timestamp: created and opened $log_file_name\n";
}
$count++;
}
}
聽起來像是使用狀態變量的一個很好的理由。 將文件句柄存儲在持久性哈希中。
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
sub log_msg {
state %fh;
my ($msg, $name) = @_;
unless ($fh{$name}) {
warn "Opening $name\n";
open $fh{$name}, '>', $name or die $!;
print {$fh{$name}} scalar localtime, " Opened file\n";
}
print {$fh{$name}} $msg, "\n";
}
log_msg('Message1', 'first.log');
log_msg('Message2', 'first.log');
log_msg('MessageA', 'second.log');
log_msg('MessageB', 'second.log');
請注意打印調用中文件句柄周圍的額外括號。 那是因為print對你可以用作filehandle參數的內容有點挑剔。
最好的方法是使用Log :: Log4perl,這樣你就不必考慮它,你可以專注於你的真實任務。
除此之外,您可以使用我們在Effective Perl Programming中介紹的文件和文件句柄的一些技巧。 幸運的是,這也是我們的出版商贈送的免費章節 。
簡而言之,您不希望在日志記錄例程中考慮這一點。 這是雜亂的代碼。 相反,創建一個方法,該方法返回緩存的文件句柄或打開它(這很像一個用於ping數據庫句柄並在需要時重新連接的方法):
sub log_msg {
my( $self, $msg, $name ) = @_;
print { $self->get_fh_by_name( $name ) } $msg;
}
BEGIN { # to define variables before the subroutine
my %log_fhs;
sub get_fh_by_name {
my( $self, $name ) = @_;
return $log_fhs{$name} if defined $log_fhs{$name};
open my $log_fh, catdir( $base_dir, $name ) or croak "...";
print $logfh ...
$log_fhs{$name} = $log_fh;
}
}
好吧,對於初學者來說, $count++
應該在你的if語句中,並且可以改為$count=1
。 您可能還想將$ count重命名為$file_opened_flag
或更有意義的東西。 除此之外,我認為這沒有錯。
我認為使用本身並沒有什么問題,但如果實際上只有1個文件需要跟蹤,為什么不將$log_fh
保留在閉包中並使用if(!$log_fh->opened())
而不是計數變量?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.