Chinaunix首页 | 论坛 | 博客
  • 博客访问: 25420
  • 博文数量: 13
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2014-01-05 16:13
文章分类
文章存档

2016年(1)

2014年(12)

我的朋友

分类: PERL

2014-02-11 15:33:20

Perl 对文件的操作

1.  复制,移动,重命名

文件系统经常会对文件进行复制和移动,Perl File:: Copy 模块可以提供方便的,跨平台的操作:

    $old_file=”f:/perlex/001.pl”;

    $new_file=”f:/perlex/002.pl”;

copy($old_file, $new_file) or die "Failed to copy: $!";复制文件

copy($old_file, \*STDOUT) or die "Failed to copy: $!";

#该操作可以将文件的内容输出到屏幕

move($old_file, $new_file) or die "Failed to move: $!";

#移动文件,可实现重命名的功能

Perl 还有内建的重命名函数rename

rename($old_file, $new_file) or die "Failed to rename: $!";

该命令比较依赖操作系统,在大多数情况下 File::Copy 下面的move指令更具有可移植性和可靠性.

对于文件的删除,perl也有一个内建命令unlink

unlink $file or die "Failed to remove $file: $!";

unlink可以删除多个文件,并返回成功删除文件的个数。但并不建议这么做。因为如果这样做的话,当文件未被删除成功的话,你不知道未被删除的是哪个文件。所以建议一次只删除一个文件

另外需要注意的是,unlink并不能够删除目录。

Perl有一些用于测试文件的操作符,在命令行中输入perl –f –x 可以列出所有这些操作符。

if( -r $file ) {

print "$file is readable.\n";

}

if( -e $file ) {

print "$file exists.\n";

}

另外,stat函数也会一次性的返回文件的大量信息

2 .Perl对目录的操作

如果需要读取目录下面的文件,可以使用opendir和相关的函数readdir。该方法返回的文件列表是按照文件系统中文件的顺序,而没有另外的排序。

opendir( HOMEDIR, $ENV{HOME} ) or die "Failed to read $ENV{HOME}: $!";

my @files = readdir(HOMEDIR);

closedir(HOMEDIR);

# 新的perl版本 (5.6.1 以上) 支持变量作为句柄

opendir( my $home, $ENV{HOME} ) or die "Failed to read $ENV{HOME}: $!";

my @files = readdir($home);

closedir($home);

# 当我们获得了文件的名字后,我们可以对这些文件进行操作

foreach my $file ( @files ) { print "$file\n"; }

Alternately, we can use glob.

my @files = glob("*.txt"); # 以。Txt结尾的文件

# or less commonly:

my @files = <*.txt>;

glob的运行速度是相对较慢的,它返回的文件列表按照ascII排序。

注:以上对目录中文件的获取,子目录被当做文件处理。当我们希望忽略子目录时,可采取以下的方法:

opendir( my $home, $ENV{HOME} ) or die "Failed to read $ENV{HOME}: $!";

foreach my $file ( readdir($home) ) {

next unless -f $file;

# process file

}

创建和移动目录

mkdir $new_dir or die "Failed to make $new_dir $!";

mkdir $new_dir, $mask or die "Failed to make $new_dir: $!";

rmdir $new_dir or die "Failed to remove $new_dir: $!";

对于函数mkdir,如果不带第二个参数测其默认为0777

对于函数rmdir,如果目录不为空,则函数执行失败。

如果需要创建和移动目录树,我们可以使用Use::Path,

use File::Path;

mkpath( ’shop/inventory/shelf’ );

mkpath( ’shop/inventory/shelf’, 0, $mode );

rmtree( ’shop/inventory/shelf’ );

mkpath 会将成功建立的目录返回,rmtree 则会删除目录及文件,并返回删除的文件的个数。

目录的路径

不同的系统可能对于目录采用不同的分隔符,这大大减低了代码的可移植性。这个时候我们可以使用File::Spec模块。

use File::Spec;

my $dir = File::Spec->catfile( ’shop’, ’inventory’, ’shelf’, ’price.txt’ );

print $dir;

my ($volume,$directories,$file) = File::Spec->splitpath( $dir );

程序的输出如下:

shop/inventory/shelf/price.txt  #Unix和类似系统

shop\inventory\shelf\price.txt# Win32 操作系统

shop:inventory:shelf:price.txt#Mac OS 9.

对目录的操作,我们可以用函数opendirreaddir来进行,但是我们也有更简便和更显得大气的方法,用标准模块File::Find

use File::Find;

my $YEAR = 365; # 一年中的天数

my $SIZE = 100_000; # 100k 字节

# 需要在命令行中传递路径

foreach my $dir (@ARGV) {

find ( \&find_old_music, $dir );

}

# 那些已经有一年没有听过的音乐,如果大小大于100K的话,列出来

sub find_old_music {

if( /(\.(mp3|ogg)$/i and -A > $YEAR and -s > $SIZE) {

print "$File::Find::name\n";

}

}

find_old_music 子函数被调用时,它有三个变量需要设置:

$_

设置成为当前文件的名字

$File::Find::dir

设置为当前目录

$File::Find::name

文件的全名,. 相当于 $file::Find::dir/$_.

File::Find 会自动将工作目录改变到当前测试的目录下边

如果你觉得上述的方法不容易理解,那么perl提供了另外一种方法File::Find::Rule

use File::Find::Rule;

my $YEAR_AGO = time() - 365 * 24 * 60 * 60; # Year ago in secs

my $SIZE = 100_000; # 100k bytes

my @old_music = File::Find::Rule->file()

->name ( ’*.mp3’, ’*.ogg’)

->atime( "< $YEAR_AGO" )

->size ( "> $SIZE" )

->in ( @ARGV );

# Do something with @old_music files

atime 返回的是从197011日开始的以秒计算的时间,



阅读(1852) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~