簡體   English   中英

如何在Perl中打開文件時才打開文件?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM