【发布时间】:2017-12-03 12:35:07
【问题描述】:
在 Windows 7 中使用 Strawberry Perl 5.22.0。有没有更“perlish”的方式来编写这个 sn-p 代码?我讨厌文件打开部分的重复,但由于需要测试创建时间,我想不出一种方法让它只打开一次。
...
my $x;
my $fh;
my $sentinelfile = "Logging.yes"; #if this file exists then enable logging
my $logfile = "transfers.log";
my $log = 0; #default to NO logging
$log = 1 if -e $sentinelfile; #enable logging if sentinel file exists
if($log){
#logfile remains open after this so remember to close at end of program!
if (-e $logfile) { #file exists
open($fh, "<", $logfile); #open for read will NOT create if not exist
chomp ($x = <$fh>); #grab first row
close $fh;
if (((scalar time - $x)/3600/24) > 30) { #when ~30 days since created
rename($logfile, $logfile . time); #rename existing logfile
open($fh, ">", $logfile); #open for write and truncate
print $fh time,"\n"; #save create date
print $fh "--------------------------------------------------\n";
} else { #file is not older than 30 days
open($fh, ">>", $logfile); #open for append
}
} else { #file not exist
open($fh, ">", $logfile); #open new for write
print $fh time,"\n"; #save create date
print $fh "--------------------------------------------------\n";
}
} #if $log
...
回顾一下:日志文件记录东西。文件的第一行包含日志文件的创建日期。第二行包含水平规则。文件的其余部分包含文本。创建文件后大约 30 天,重命名文件并开始一个新文件。在上述代码块之后,日志文件已打开并准备好记录内容。它在程序的其余部分结束时关闭。
【问题讨论】:
-
为什么不创建一个计划任务来处理每个月的日志轮换?那么这个脚本只需要 1 个打开调用(在附加模式下)。
-
如果您不想执行计划任务日志轮换,那么我会重写您的代码以使用 2 个单独的子程序;一个用于旋转日志,另一个用于获取日志文件的 ctime。然后你可以有一个像这样的简单语句
rotatelog($logfile) if log_ctime($logfile) > 30; -
@NetMage 下一条语句就是:
open( $fh, ">>", $logfile );。您可以向其中添加 die 语句或加载autodiepragma。这两条语句将是 OP 的if ($log) {块中唯一需要的行。 -
你能举一个需要多次打开的例子吗?由于 Windows 上的 ctime 值不会像在 *nix 系统上那样改变,我们可以检查该值而不是打开和读取文件中的时间戳(如 zdim 所示)。所以文件只需要打开/关闭一次。