Perl语言入门学习笔记-10
上一篇 / 下一篇 2007-10-29 19:08:31 / 个人分类:编程吧
mNAAp7F:L;fslo0文件测试51Testing软件测试网z#h(q8TR-jvv"i
51Testing软件测试网9RDvKm基本格式:文件测试操作符 + 文件名/文件句柄51Testing软件测试网*p$KF
TF5S
返回值一般为真或假,或其他一些结果。
4Hx|a1WV
nrZc0+文件的访问权限测试
?W"]~Woh0-r, -w, -x, -o: 测试文件或目录对当前有效的用户或组(即当前负责运行程序的“人”)是否可读、可写、可执行或所拥有。51Testing软件测试网s5N:QiL Ik
-R, -W, -X, -O: 测试文件或目录对实际的用户或组是否可读、可写、可执行或所拥有。
'V'o l~q3B0-O和-o只测试用户标识符,不测试组标识符。
5dFn6\7p7\0+文件类型测试51Testing软件测试网J/e(]I#wM
-f, -d, -l, -S, -p, -b, -c: 测试文件句柄是否为普通文件、目录、符号链接、Socket、pineline、块设备、字符设备
.iFs$d(N]g0-T: 测试文件是否看起来像文本文件
.dzd8P2f&a#zf ReL0-B: 测试文件是否看起来像二进制文件51Testing软件测试网D;_:~c ]Q
Perl会打开文件,检查开头的几千个字节。如果有很多空字节、控制字符和设定了高位(第八位为1)的字节,那么该文件看起来像二进制文件。如果很平常,那么该文件看起来像字节文件。对于很多非ASCII码的字符集, Perl可能会猜错。51Testing软件测试网}*?:kG'q$G7M
如果文件不存在,-T和-B都会返回假;如果文件为空,-T和-B都会返回真。51Testing软件测试网%@ PF:v)|
{7q;M)`
-t: 测试文件句柄是否为具有交互能力的tty设备,如STDIN(键盘)。普通的文件和管道没有交互的能力。
mu.vLI)~p9q0+文件存在性测试
iwaI&Q'z0-e, 测试文件或目录是否存在
9Sh;Xf,^v2Q"R0L8n\0die "Opps! A file called '$filename' already exists.\n" if -e $filename;
"Fp-m4wd"u0-z, 测试文件是否存在并且没有内容,对目录来说永远为假51Testing软件测试网p/SdAf`T
A}7]
-s, 测试文件或目录是否存在,并返回文件大小(以字节为单位)
agl4eX_0+文件时间戳测试51Testing软件测试网F3z["t*p[
-M, -A, -C测试文件最后被修改、最后被访问、inode被改变(有的系统指文件创建)到现在的天数,这个时间值为浮点数。51Testing软件测试网"N9]K9Q"]a^Nh:W"n
检查时间的原点为程序开始运行的时刻,这取决于变量$^T的值,可以修改这个变量。51Testing软件测试网D|\Fy9_
w1{
如果某个天数为负数,说明那个程序已经运行了一段时间,才找到某个刚刚才被访问到的文件,或者这个文件的时间戳被设置成了未来时间。51Testing软件测试网:t[E\E)u-G-v
warn "Config file is looking pretty old!\n"51Testing软件测试网9tg8r"Eec5RA@'k
if -M CONFIG > 28;
xv/uNu
Goy/_7X0my @original_file=qw/ ... /;51Testing软件测试网6}0@"?%_.T1?"r
my @big_old_files;51Testing软件测试网` co%?,C
foreach my $filename(@original_file) {51Testing软件测试网vrw\p;V
push @big_old_files, $filename51Testing软件测试网U4Fu[d
mgR
if -s $filename > 100_000 and -A $filename > 90;
"\*]V/d,Q1J8}e+r6n0}51Testing软件测试网oX%^
GW X
+文件其他属性测试
H \5Hn)b"Z*\,|m v0-u, -g, -k测试文件或目录是否设置了setuid、setgid、sticky位
|4Ftk%n u~0如果文件测试操作符后面没有写文件名或文件句柄,默认参数是$_里的文件名称。
k[,d%A{0foreach (@lots_of_filenames) {51Testing软件测试网8{rv8cgF P
print "$_ is a readable\n" if -r;
U(s.I#R'X-[0 my $size_in_KB= (-s) / 1024;
6D8juZq{I0 #-s必须加上(),否则会把/ 1024也当成参数的一部分
1O6L+Ca6^
G#j0 ...51Testing软件测试网:mv Z*Ws,z1Y"|
}
6nw [:iKc2P8r051Testing软件测试网6P.m:JTh9w
+stat和lstat函数
K8~Z\I Bu0通过stat函数来获取文件的详细信息。51Testing软件测试网Y]g#c
Bw)q3M"{M
参数:文件名或文件句柄,默认参数:$_51Testing软件测试网e*dEF{N)U;p
返回值:含有13个元素的列表或空列表(此时函数执行失败),若底层系统调用失败,则返回undef
*fk8M
h S3W'u0my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks)=stat($filename);
je2oh%?Ok `0$dev和$ino: 文件的设备编号和inode编号,其组合独一无二。
Zdd)q
BZ0$mode: 文件的权限位组合,用八进制数字表示
X:jcAeSy0$nlink:文件或目录的(硬)链接数目
2e8\x&S!TOWc*C/{(M0$uid, $gid: 不说了51Testing软件测试网^Zq0q(E
N*D
$size: 同-s的返回值
+O@lEz;sD0$atime, $mtime, $ctime: 三种时间戳,以系统的时间格式表示,32位整数,表示从纪元(Epoch,计量系统时间的基准点)开始计算的秒数。在Unix系统中,纪元为1970年世界标准时间的午夜。怎样把时间戳的值转换成我们常用的时间格式?51Testing软件测试网 Ym b!]*C
对符号链接的名称使用stat函数,返回的是该链接所指对象的信息。若要返回符号链接本身的信息,使用lstat函数。如果lstat的参数不是符号链接,它会返回同stat一样的信息。51Testing软件测试网}Q
U4z|,R^H,C
Q'F3aqrQk!S/e0+localtime函数51Testing软件测试网)_"`\2P5^S6f'x
标量上下文
(Ae`TdH/N;C2MQh0my $timestamp=1180630098;51Testing软件测试网.B3Y+]&o+RN5O
my $date=localtime $timestamp;
o:z!JR3IvS0#把时间戳转换为可读的时间字符串:
U"B4qfn#cX+hw0#Fri Jun 1 00:48:18 20071851Testing软件测试网@/q+d1k d
列表上下文
)rT
n%N [|H8W%f:Btq0my ($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst)=localtime $timestamp;51Testing软件测试网4M4beu@\u
#18,48,0,1,5,107,5,151,0
[pst+E[;Q0$mon从0到11,$year从1900年算起的年份, $wday从0到6,$yday从0到364(365)。
hX#dt1g
D8`AQ5F!C1M0my $date=localtime; #默认情况下返回系统当前时间
2?:xDv6VHi+b0my $date=gmtime; #默认情况下返回系统当前时间(世界标准时间)
A-h3jaw U,R@0b3TB0my $date=time; #默认情况下返回系统当前时间的时间戳
vPk`4\6B0#使用Time::Local模块中的timelocal函数,用年月日等信息获
|q#]0oq#t;|'t0#得对应的时间戳51Testing软件测试网TgmQ#G9v3y@vP
use Time::Local;
r"iK.Ew"GaIr5oH0my $time=timelocal($sec,$min,$hr,$day,$mon,$yr);51Testing软件测试网p%Sog5^8XD_
51Testing软件测试网 K T6Y^&[hS
+逐位运算操作符(bitwise operator)51Testing软件测试网{,Hu+Fxt^
10 & 12 = 8: 逐位and,先把操作数转换为二进制,再进行运算51Testing软件测试网Od
OJs2KN$Z2S
10 | 12 = 14: 逐位or51Testing软件测试网3oKzg!z5z+v*}
10 ^ 12 = 6: 逐位xor(异或)
qK-u*PrB;W06 << 2 = 24: 将左操作数逐位左移(右操作数)位,用0补足最低位 000110 -> 011000
MP |7M}l&A025 >> 2 = 6: 将左操作数逐位右移(右操作数)位,丢弃移出的最低位 011010 -> 00011051Testing软件测试网uoo;H}/_"n
~10 : 逐位取反,也称为取1的补码 00001010 -> 11110101(0xf5)
i2[4p%z%x%[.u0#$mode是stat函数从配置文件返回的值51Testing软件测试网`Br
X!T2i CVb
warn "The configuration file is world-writable!\n"
VI0p
Pj t;a(m0 if $mode & 0002;
k @&CN3O z)bv;g0 #配置文件对所有用户可写,安全性有问题
x Mo y:c![M0 my $classical_mode=0777 & $mode; #屏蔽最高位
Q-[s:u(cJ0 my $u_plus_x=$classical_mode | 0100; 51Testing软件测试网P#oY:g `U%z
#将owner执行权限位设为151Testing软件测试网PK9R jN"~(u
x/g
my $go_minus_r=$classical_mode & (~0044);
TE?C"L;V%c0 #把两个位设为051Testing软件测试网!j&i3hQS`K
逐位运算操作符的操作数可以是位字符串(Perl对长度没有限制),也可以是整数(至少32位)。51Testing软件测试网Fd/w7_(yR.B
"\xAA" | "\x55" = "\xFF"
k%yQo$b
H {2K6sV#k#K0
r$Hw4z3Z0+下划线文件句柄(需要进一步深入理解)51Testing软件测试网*C{~t0t_W
程序里每次使用stat, lstat, 或某个文件操作符时,Perl必须向系统请求该文件的stat缓冲区(这实际上是stat系统调用返回的缓冲区)。51Testing软件测试网.w)?%{TR]
用_文件句柄做参数,Perl从内存中找出前一次文件测试,stat,lstat的参考信息,而不是向系统再要一次数据。可以减少不必要的系统调用,使程序的运行速度更快。需要注意的是,可能某个子例程内部调用过stat,将预期的缓冲区的内容覆盖。51Testing软件测试网1LRU]'e
my @original_files=qw/ fred barney betty wilma /;51Testing软件测试网CH}*|@+f
my @big_old_files; #要做备份的文件列表51Testing软件测试网MwJ7Gz&U!T-S~/A
foreach (@original_files) {51Testing软件测试网0f%L"]n
IV
push @big_old_files, $_
c$s3l'DL5H-y,}L0 if (-s) > 100_100 and -A _ > 90;51Testing软件测试网8Y3_H kd2h
#buf.st_size > 100000 && buf.st_atime > 9051Testing软件测试网8R^}c$}YV
#第二个测试使用了第一个测试留下来的数据
;gxPw9`kV0}
B2y+I-eh:[1J j&E5`0参考:stat/lstat系统调用
.`c3vi/Q]0#include <sys/types.h>51Testing软件测试网
c'ctXv
~u
#include <sys/stat.h>51Testing软件测试网*d-p3uv YrK!Q
#include <unistd.h>
Y$TW8}6k br\H0
H8^5y.AR X{0int stat(const char *path, struct stat *buf);
5A?I7q8e7P0int fstat(int filedes, struct stat *buf);
!Tj3_%hL{#V,a0int lstat(const char *path, struct stat *buf);
oY%]4B0~ OTp7~a%d0
c8A*@,v+n!K0参数: 51Testing软件测试网0xG.U"h#B~;n
path:文件路径名。 51Testing软件测试网`y9Kz FCQ
buf:是结构体stat的指针51Testing软件测试网,`/@ ock+uk
51Testing软件测试网,l5`0UqX
}
Zu
返回值: 51Testing软件测试网dqyYg4u
成功执行时,返回0。失败返回-1。有相应的错误码。51Testing软件测试网%e-fkNd*@CQE
ts#l1g3^$v0struct stat {
`d+?Co5]0B.gy0 dev_t st_dev; /* 文件所在设备的标识 */
#{R Orsx)_0 ino_t st_ino; /* 文件结点号 */51Testing软件测试网bOyxu/g_+os
mode_t st_mode; /* 文件保护模式 */
R/v\[-sVP9pn+F0 nlink_t st_nlink; /* 硬连接数 */
1okU'Q;h$q4_Rv0 uid_t st_uid; /* 文件用户标识 */51Testing软件测试网"p5RNjWY%z
gid_t st_gid; /* 文件用户组标识 */51Testing软件测试网9wT$Rh;T? I PwkmN:t
dev_t st_rdev; /* 文件所表示的特殊设备文件的设备标识 */
7e7FP+?-}&q8s$u0 off_t st_size; /* 总大小,字节为单位 */
W2}e)?&r$Dq7s0 blksize_t st_blksize; /* 文件系统的块大小 */
o8M'o+PL@0 blkcnt_t st_blocks; /* 分配给文件的块的数量,512字节为单元 */51Testing软件测试网Q"I$i6Ny8\s
time_t st_atime; /* 最后访问时间 */51Testing软件测试网kv:z/}xO
time_t st_mtime; /* 最后修改时间 */51Testing软件测试网]"v{*\!w"@3L{S
time_t st_ctime; /* 最后状态改变时间 */
wt
zY.[0};
i!ra;H HS'R0
Ks7hr#z&H[v0习题2 Which is the oldest file?51Testing软件测试网-_l.neIkl'R4NJ-o
%f:V"^0H~.mp0#!/usr/bin/perl -w51Testing软件测试网jWN0U3p
JR4E!u
7^4Dp%?,]d\0use strict;51Testing软件测试网 e*F3Vn![4y]
51Testing软件测试网t r.m@Bif (@ARGV==0) {51Testing软件测试网
]]Q%NGlLig
print "Usage: ./file_test arg1, arg2, ...","\n";51Testing软件测试网t2v
k:s0S"S
M
} else {