学习文件操作。

句柄名字最好使用大写字母,这样就不会与保留字foreach,else,if等发生冲突。

如果文件句柄名字重复使用,即另一个文件用相同的文件句柄名字打开,那么原始文件句柄将先被关闭,然后重新打开。

打开文件时的异常处理:
$!在数字上下文中返回错误号,在字符串上下文中返回错误信息。
抛出异常信息时,die中断程序,warn不中断程序。
抛出异常信息时,带\n则不输出更多信息,否则要有at filename line XXX。

练习(f61.pl):

 
  
  1. $ cat f61.pl  
  2. #!/usr/bin/perl -w  
  3. open(F51,"XXXX.XX"or warn "Can not open file: $!";  
  4. open(F51,"XXXX,XX"or warn "Can not open file: $!\n";  
  5. open(F51,"abc.txt"or die "Can not open file: $!";  
  6. $contents = <F51>;  
  7. #chomp $contents;  
  8. print qq(\n\$contents=$contents);  
  9. @contents = <F51>;  
  10. #chomp @contents;  
  11. print qq(\n\@contents=@contents);  
  12. close(F51);  
  13. open(F51,"abc.txt"or die "Can not open file: $!";  
  14. print("\n use operator <> read lines: \n");  
  15. while(<F51>){  
  16.         print(qq($_));  
  17. }  
  18. close(F51); 

$ perl f61.pl
Can not open file: No such file or directory at f61.pl line 2.
Can not open file: No such file or directory

$contents=first line

@contents=second line
 third line

 use operator <> read lines:
first line
second line
third line
 

写文件和打开文件语法相似,不同的是路径前加>表示打开时先清空文件,>>表示从文件末尾添加。


练习(f62.pl):

 
  
  1. #!/usr/bin/perl -w  
  2.  
  3. open(F51,">efg.txt"or die $!;  
  4.         print F51 "line 1\n";  
  5.         print F51 "line 2\n";  
  6.         print F51 "line 3";  
  7. close(F51);  
  8.  
  9. print("\nshow file:\n");  
  10. system("cat efg.txt");  
  11.  
  12. open(F51,">>efg.txt"or die $!;  
  13.         print F51 "\nline 4";  
  14. close(F51);  
  15.  
  16. print("\nshow file:\n");  
  17. system("cat efg.txt");  
  18.  
  19. print("\n"); 

$ perl f62.pl

show file:
line 1
line 2
line 3
show file:
line 1
line 2
line 3
line 4
 

当你将数据写入一个文本文件时, P e r l将\ n字符序列转换成你的操作系统使用的记录分隔符。在U N I X中,\ n变成一个ASCII 10(L F);在M a c i n t o s h上,\ n转换成ASCII 13(C R);在D O S和Wi n d o w s系统上,它变成序列ASCII 13和ASCII 10(C R L F)。

每当你真的想要写入二进制数据并且不希望P e r l或操作系统对它进行转换时,你必须使用b i n m o d e函数,将文件句柄标记为二进制文件。应该在文件句柄打开之后和对它进行输入输出之前使用b i n m o d e。

open(F51,"abc.gif") or die "$!";
binmode(F51);
#...
print F51 "...";
#...
close(F51);

对文件进行检查:
                   -r  File is readable by effective uid/gid.
                   -w  File is writable by effective uid/gid.
                   -x  File is executable by effective uid/gid.
                   -o  File is owned by effective uid.

                   -R  File is readable by real uid/gid.
                   -W  File is writable by real uid/gid.
                   -X  File is executable by real uid/gid.
                   -O  File is owned by real uid.

                   -e  File exists.
                   -z  File has zero size (is empty).
                   -s  File has nonzero size (returns size in bytes).

                   -f  File is a plain file.
                   -d  File is a directory.
                   -l  File is a symbolic link.
                   -p  File is a named pipe (FIFO), or Filehandle is a pipe.
                   -S  File is a socket.
                   -b  File is a block special file.
                   -c  File is a character special file.
                   -t  Filehandle is opened to a tty.

                   -u  File has setuid bit set.
                   -g  File has setgid bit set.
                   -T  File is an ASCII text file (heuristic guess).
                   -B  File is a "binary" file (opposite of -T).

                   -M  Script start time minus file modification time, in days.
                   -A  Same for access time.
                   -C  Same for inode change time (Unix, may differ for other platforms)

               Example:

                   while (<>) {
                       chomp;
                       next unless -f $_;      # ignore specials
                       #...
                   }

看到一句话也许有用:getc能够从文件读取单字符输入。

继续学习:
不同的操作系统和不同的文件系统需要使用不同类型的锁定机制。
flock函数可以给UNIX和NT下的文件加锁。lock_SH共享锁,lock_EX专用锁。关闭文件自动释放锁,lock_UN释放锁很少需要这样做。
因为要先open后lock,这两个操作有空档,通过一个辅助文件可实现open前加锁。所有程序都先去锁信号文件,锁定信号文件成功后再open数据文件。
 

练习(f63.pl):

 
  
  1. #!/usr/bin/perl -w  
  2. use Fcntl qw(:flock);  
  3.  
  4. my $lock_file1="/usr/tmp/lock1.lck";  
  5. sub get_lock1 {  
  6.         open(LOCK1,">$lock_file1"or die $!;  
  7.         flock(LOCK1,LOCK_EX) or die "Lock failed: $!";  
  8. }  
  9. sub release_lock1 {  
  10.         close(LOCK1);  
  11. }  
  12. print "press any key to get lock1:";  
  13. $WAIT=<STDIN>;  
  14. get_lock1();  
  15. print("\nget lock1,input your text to file efg.txt: ");  
  16. open(F1,">efg.txt"or die $!;  
  17. $WAIT=<STDIN>;  
  18. print F1 $WAIT;  
  19. close(F1);  
  20. print("\npress any key to release lock1 and exit:");  
  21. $WAIT=<STDIN>;  
  22. release_lock1();  
  23. print qq(\n); 

练习文件锁需要开两个窗口,下面是练习过程:
 

111

flock上锁不是操作系统级别的,只是程序之间的约定。例如:程序A用flock加锁,程序B不用flock仍然可以操作文件。flock用于A,B之间约定不要同时操作同一个文件。

这次就到这。