perl 文件操作

perl中文件操

基础

  在Perl中,提供了三种文件句柄:STDIN,STDOUT,STDERR.它们可以由父进程建立的文件或者设备会自动打开.一般使用open函数来建立文件句柄.open函数的语法是只读模式时为:
  open (FILEHANDLE,"somename");
  其中FILEHANDLE是文件句柄的名字,常用写法是全部大写字母(没有特殊规则,没有特殊前缀).而somename就是你要打开的文件或设备名字.这种方法打开的文件只可进行读取动作.若要打开文件并需要进行写入动作,可以用大于符放到文件名字前面,语法就是覆盖模式了:
  open (FILEHANDLE,">somename");

  当然,如文件中早存在其他资料,你想在其后增加数据而不对原来数据进行任何动作的话,这个符号可以帮助你:>>,语法就变成了附加模式:
  open (FILEHANDLE,">>somename");
  另外,文件打开有时候会失败(例如文件不存在,文件名字错了等因素存在).所以在程序里应该对文件打开成功与否进行测试,常用的方法是在open函数调用时利用其返回true/false的值,进行die短路效应测试,它的语法是:
  open (FILEHANDLE,">somename") || die "error message:$!";
  很多人不知道什么叫"短路效应",就让这个例子来为我们说明吧:譬如打开文件成功,则open函数返回true,此时因为||是OR逻辑,一个为真,则后面的没有必要也没有进行执行动作,所以就忽略(这和电子学上"短路了"一样的道理)了die的执行;而在open函数返回false的时候,因为OR逻辑前一个为假,它必须执行右边的die函数.
  或许是die函数太难听了(开玩笑的),perl还提供了一个类似的函数warn,它与die很像:
  open (FILEHANDLE,">somename") || warn "error message\n";
 
 安全的打开了文件,那该如何使用呢? 其实使用文件句柄读取数据,就跟从STDIN中读取数据方法相同,举个例子吧:
  open (FH,"test.txt");
  while(<FH>) {
    chomp
    print "i saw $_ in the test.txt";
  }

  如果你用覆盖或者附加方式打开文件(<和<<),而且想用print函数对它进行写入,则语句可以这样写:
  print FILEHANDLE "data";
  data是你要写入的数据,看清楚,FILEHANDLE和data之间没有逗号,只有空格!
  在print函数里,其实我们还可以累赘的写成这样:
  print STDOUT "hello,world!\n";
  但print默认就是向STDOUT输出.所以此语句变的有点累赘且没必要.
  当然,用完了文件,就要关闭:
  close(FILEHANDLE);
  虽然程序关闭时自动关闭所有开启的文件句柄,但养成检查关闭习惯对良好的程序设计是非常有帮助.
  基本的文件操作已经学完,让我们来举个把a.txt文件内容拷贝到b.txt文件的例子吧:
  open(INP,"a.txt") || die "can't open a.txt:$!";
  open(OUT,"b.txt") || die "can't open b.txt:$!";
  while(<INP>) {
    print OUT $_;
  }
  close(IN) || die "can't close a.txt:$!";
  close(OUT) || die "can't close b.txt:$!";

 

打开多文件

  如过我们要打开的,并非一个文件,而是多个同后缀的文件.那我们逐一打开它吗?
  并不需要!
  在UNIX里,可以用echo命令浏览所有符合规则的文件:
  echo *.txt
  而在perl中,我们可以使用glob函数(也有人叫它做"file glob").它的用法和<STDIN>也很相同:它每次会返回一个在当前目录下,符合条件的文件名.如果所有符合条件的文件名都已经传完,它就返回undef.
 

比如要读取/home/globtest目录中的所有.pl文件,可以这样写:

  @plFiles = glob '/home/globtest/*.pl';

 又如:

  while (my $file = glob "*.dat" )
{
     open my $fh, '+>', "$file" or die $!;
     while (<$fh>)
     {

     }
}

件测试

  新开一个文件时,在安全角度来讲绝对有必要进行同名文件是否已存在的测试.在shell脚本里,可以用-e filename做这件事情,而在Perl中也很像:-e $filename.若文件存在返回真,否则返回假.例子如:
  $filename = "a.txt";
  if(-e $filename) {
     # 这里写存在文件的情况
  } else {
     # 这里写不存在文件的情况
  }

  还可以对文件句柄进行可读/可写测试.分别是-r,-w.用法和上面-e $filename一样.如检测一个文件是否可读可写,则可以:
  if(-r filename && -w filename)
  {
     # 这里可进行读写操作.
  }

下面给出文件测试和它的意义的列表:
  -r 文件或目录可读
  -w 文件或目录可写
  -x 文件或目录执行
  -o 文件或目录归用户所有
  -R 文件或目录对真正用户可读
  -W 文件或目录对真正用户可写
  -X 文件或目录对真正用户执行
  -O 文件或目录归真正用户所有
  -e 文件或目录存在
  -z 文件存在且大小为0
  -s 文件或目录存在且不为0(返回字节数)
  -f 文件为普通文件
  -d 文件为目录
  -l 文件为符号链接
  -p 文件为命名管道(FIFO)
  -S 文件为一个套口(socket)
  -b 文件为块特殊文件
  -c 文件为字符特殊文件
  -t 打开tty控制台的文件句柄
  -u 文件或目录是设置用户ID号
  -g 文件或目录是设置用户组ID号
  -k 文件或目录的sticky位置位
  -T 文件是文本文件
  -B 文件是二进制文件
  -M 以天为单位的存在时间
  -A 以天为单位访问时间
  -C 以天为单位同代码更改时间

其中大部分是返回true/fals,其中几个例外:
-s:如果文件不是空,返回真.不过这个"真"是文件的长度.(单位是byte.)
-M,-A,-C:返回的是时间,全部用天或1/2天的单位表示,所以36小时被表示为1.5天(如果比较某一个文件比后一个文件早一分钟(或者短时间的比较)的话,你可能要用rangecomparision的方法.).

改头换"名"

  为某个文件改名字,可以使用rename函数并进行die短路测试:
  rename ("old-filename","new-filename") || die "error message:$!";

删除文件

  用unlink函数,可以删除文件,语法是:
  unlink ("filename");

打开目录句柄

  语法:opendir(DIRECTORY-NAME,"dir") || die "error message:$!";
  例子:opendir(DH,"/mp3") || die "打开目录错误:$!";

关闭目录句柄

  语法:closedir(DIRECTORY-NAME);
  例子:closedir(DH);

创建目录

  语法:madir("DIRECTORY-NAME",permission) || die "error message:@!";
  
其中Permission表示权限的意思.如0777

删除目录

  语法:rmdir("DIRECTORY-NAME"); # 当然,也可以进行die短路测试

你可能感兴趣的:(perl,文件)