Exercise for Chapter 7 of "Intermediate Perl"

本文详细解读了《中级Perl》一书中章节7的练习题,包括使用File::Find模块进行文件查找、本地时间处理及目录遍历等关键概念。通过实际代码演示,帮助读者理解如何在Perl中高效地进行文件操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#########################################################################
# Brief: Exercise for Chapter 7 of "Intermediate Perl"
# File: ch7_exam.pl
# Creator: thinkhy
# Date: 12/23/2012
#########################################################################
use File::Find;
use Time::Local;
use File::Spec::Functions qw(canonpath no_upwards);
my $target_dow = 2; # Sunday is 0, Monday is 1, ...
my @starting_directories = (".", "e:/tmp");
my $seconds_per_day = 24 * 60 * 60;
my($sec, $min, $hour, $day, $mon, $yr, $dow) = localtime;
my $start = timelocal(0, 0, 0, $day, $mon, $yr); # midnight today
while ($dow != $target_dow) {
# Back up one day
$start -= $seconds_per_day; # hope no DST! :?)
if (--$dow < 0) {
$dow += 7;
}
}
my $stop = $start + $seconds_per_day;
my($gather, $yield) = gather_mtime_between($start, $stop);
find($gather, @starting_directories);
my @files = $yield->( );
for my $file (@files) {
my $mtime = (stat $file)[9]; # mtime via slice
my $when = localtime $mtime;
print "$when: $file\n";
}
sub gather_mtime_between {
my $start_time = shift;
my $end_time = shift;
my @files = ();
#########################################################################
# Here use canonpath, details explained as below
# canonpath:
# No physical check on the filesystem, but a logical cleanup of a path.
# no_upwards:
# Given a list of file names, strip out those that refer to a
# parent directory. (Does not strip symlinks,
# only '.', '..', and equivalents.)
# Refer to http://perldoc.perl.org/File/Spec.html
#
# Also, notice that when using stat inside the callback, the filename is $_
# but when the filename reperting to the user, the name is $File::Find::name
# because different current working directory for callback and user function
#########################################################################
sub {
my $when = (stat $_)[9];
push @files, canonpath( $File::Find::name )
if ($when >= $start_time and $when <= $end_time) },
sub { @files = no_upwards( @files );
wantarray ? @files : [ @files ] }
}
# Here is the 'official' answer for Chapter 7
sub gather_mtime_between {
my($begin, $end) = @_;
my @files;
my $gatherer = sub {
my $timestamp = (stat $_)[9];
unless (defined $timestamp) {
warn "Can't stat $File::Find::name: $!, skipping\n";
return;
}
push @files, $File::Find::name
if $timestamp >= $begin and $timestamp <= $end;
};
my $fetcher = sub { @files };
($gatherer, $fetcher);
}
 
############################################################################
# Compared with answer, I omitted a special condition that the timestamp
# will be undef if the stat fails for some reason. That can happen, for example,
# if it finds a dangling symbolic link(the target file doesn't exist).
# In that case, the callback warns the user and returns early.
# With the code of answer, if we omit that check, we can get warnings of 
# an undefined value during the comparison with begin time and end time.
############################################################################

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值