Tải bản đầy đủ (.docx) (8 trang)

Tước hiệu tệp và kiểu thử tệp

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (110.43 KB, 8 trang )

Tớc hiệu tệp và kiểm thử tệp
Tớc hiệu tệp là gì?
Tớc hiệu tệp là tên trong một chơng trình Perl dành cho việc nối giữa tiến trình
Perl của bạn và thế giới bên ngoài. Chúng ta đã thấy và dùng tớc hiệu tệp một cách
không tờng minh: STDIN là một tớc hiệu tệp, đặt tên cho việc nối giữa tiến trình Perl
và lối vào chuẩn của UNIX. Giống nh vậy, Perl cung cấp STDOUT (cho lối ra chuẩn)
và STDERR (cho lối ra chuẩn cho lỗi). Những tên này là trùng với các tên đợc dùng
trong bộ trình th viện vào/ra chuẩn của UNIX, Perl dùng chúng cho hầu hết việc
vào/ra.
Tên tớc hiệu tệp cũng giống nh tên dành cho các khối có nhãn, nhng chúng đến từ
một không gian tên khác (cho nên bạn có thể có một vô hớng $fred, một mảng @fred,
một mảng kết hợp %fred, một chơng trình con &fred, một nhãn fred, và bây giờ một t-
ớc hiệu tệp fred). Giống nh nhãn khối, tớc hiệu tệp đợc dùng không cần một kí tự đặc
biệt đứng trớc, và do vậy có thể bị lẫn lộn với các từ dành riêng hiện có hay trong t-
ơng lai. Một lần nữa, khuyến cáo của Larry là bạn hãy dùng tất cả các chữ
hoa trong tớc hiệu tệp của mình - không chỉ nó biểu thị tốt hơn, mà nó cũng sẽ đảm
bảo rằng chơng trình của bạn sẽ không hỏng khi các từ dành riêng tơng lai đợc đa
vào.
Mở và đóng một tớc hiệu tệp
Perl cung cấp ba tớc hiệu tệp, STDIN, STDOUT, STDERR, mà tự động mở cho
các tệp hay thiết bị do tiến trình cha mẹ của chơng trình này đã thiết lập (có thể là lớp
vỏ). Bạn dùng toán tử open() để mở các tớc hiệu tệp phụ, hệt nh bạn làm trong chơng
trình đợc viết trong C. Cú pháp của nó giống thế này:
open (FILEHANDLE, tên nào đó);
với FILEHANDLE là tớc hiệu tệp mới, còn tên nào đó là tên tệp UNIX ngoài
(nh một tệp hay thiết bị) mà sẽ đợc liên kết với tớc hiệu tệp mới. Việc gọi này mở tớc
hiệu tệp để đọc. Việc mở một tệp để ghi thì cung dùng cùng toán tử open, nhng phần
tiền tố của tên tệp có một dấu lớn hơn (nh trong vỏ):
open (OUT, >outfile);
Chúng ta sẽ thấy trong mục Dùng tớc hiệu tệp, dới đây cách sử dụng tớc hiệu
tệp này. Cũng vậy, nh trong vỏ, bạn có thể mở một tệp để thêm vào sau bằng việc


dùng hai dấu lớn hơn làm tiền tố, nh trong:
open (LOGFILE, >>mylogfile);
Tất cả ba dạng này của open đều cho lại đúng nếu việc mở thành công và sai nếu
thất bại. (Việc mở một tệp đa vào sẽ sai, chẳng hạn, nếu tệp đó không có hay không
thể thâm nhập tới đợc bởi không đợc phép; việc mở tệp đa sẽ sai nếu danh mục không
cho ghi hay không cho thâm nhập tới.)
Khi bạn kết thúc với một tớc hiệu tệp, bạn có thể đóng nó bằng toán tử close, tựa
nh:
close(LOGFILE);
Việc mở lại một tớc hiệu tệp cũng làm đóng tệp mở trớc đó một cách tự động,
cũng nhu khi ra khỏi chơng trình. Vì điều này, phần lớn các chơng trình Perl không
bận tâm với close(). Nhng nó vẫn có đó nếu bạn muốn đợc chặt chẽ hay chắc chắn
rằng tất cả dữ liệu đều đợc đẩy ra hết đôi khi sớm hơn việc kết thúc của chơng trình.
Một chút tiêu khiển: die()
Ta hãy coi đây nh là một chú thích cuối trang lớn, nhng lại nằm ở giữa trang.
Một tớc hiệu tệp mà không đợc mở thành công thì có thể vẫn đợc dùng mà thậm
chí không gây ra cảnh báo gì nhiều lắm trong toàn bộ chơng trình. Nếu bạn đọc từ tớc
hiệu tệp thì bạn sẽ nhận đợc ngay cuối tệp. Nếu bạn ghi lên tớc hiệu tệp thì dữ liệu cứ
im ỉm bị bỏ đi (giống nh lời hứa hẹn vận động bầu cử năm trớc).
Thờng bạn muốn kiểm tra lại kết quả của việc mở tệp và báo cáo lại lỗi nếu kết
quả không phải là điều bạn dự kiến. Chắc chắn, bạn có thể rải rắc trong chơng trình
của mình với những thứ kiểu nh:
unless (open(DATAPLACE, >/tmp/dataplace)) {
print Rất tiếc, tôi không thể tạo đợc /tmp/dataplace\n;
} else {
# phần còn lại chơng trình của bạn
}
Nhng đấy là cả đống việc. Và điều thờng xẩy ra với Perl là đa ra một lối tắt. Toán
tử die() lấy một danh sách bên trong dấu ngoặc tròn tuỳ chọn, phun ra danh sách đó
(giống nh print) trên lối ra lỗi chuẩn, và rồi kết thúc tiến trình Perl (tiến trình đang

chạy chơng trình Perl) với một trạng thái ra khác không của UNIX (nói chung chỉ ra
một cái gì đó bất thờng xẩy ra). Cho nên, viết lại đoạn mã trên thì ta sẽ thấy nó giống
nh thế này:
unless (open(DATAPLACE, >/tmp/dataplace)) {
die Rất tiếc, tôi không thể tạo đợc /tmp/dataplace\n;
}
# phần còn lại chơng trình của bạn
Nhng chúng ta thậm chí còn có thể đi thêm một bớc nữa. Nhớ rằng ta có thể dùng
toán tử (logic hoặc) || để làm ngắn thêm điều này, nh trong
unless (open(DATAPLACE, >/tmp/dataplace)) ||
die Rất tiếc, tôi không thể tạo đợc /tmp/dataplace\n;
Vậy die sẽ đợc thực hiện chỉ khi kết quả của open là sai. Cách thông dụng để đọc
điều này là hãy mở tệp đó ra nếu không thì chết quách đi cho rồi! và đó là cách dễ
dàng để nhớ bất kì khi nào dùng toán tử logic và hay logic hoặc.
Thông báo vào lúc chết (đợc xây dựng từ đối của die) có tên chơng trình Perl và
số dòng đợc gắn tự động vào, cho nên bạn có thể dễ dàng xác định đợc die nào trong
chơng trình của bạn chịu trách nhiệm cho việc ra không đúng lúc này. Nếu bạn
không thích số dòng hay tệp bị lộ ra, thì phải chắc chắn rằng văn bản chết có một dấu
dòng mới ở cuối. Chẳng hạn:
die bạn nấu nớc xốt - lợn sữa;
sẽ in ra tên tệp và số dòng, trong khi
die bạn nấu nớc xốt - lợn sữa\n;
thì không in ra tên tệp và số dòng.
Dùng tớc hiệu tệp
Một khi tớc hiệu tệp đợc mở ra để đọc thì bạn có thể đọc các dòng từ nó hệt nh
bạn có thể đọc từ lối vào chuẩn với STDIN. Vậy, chẳng hạn, để đọc các dòng từ tệp
mật hiệu:
open (EP, /etc/passwd);
while (<EP>) {
chop;

print Tôi thấy $_ trong tệp mật hiệu!\n;
}
Lu ý rằng tớc hiệu tệp mới mở đợc dùng bên trong dấu ngoặc nhọn hệt nh ta đã
dùng STDIN trớc đây.
Một tớc hiệu tệp mở ra để ghi hay hiệu đính đều phải đợc cho nh một đối của
toán tử print, xuất hiện ngay sau từ khoá print nhng trớc danh sách đối:
print LOGFILE Khoản mục kết thúc của $max\n;
print STDOUT Xin chào, mọi ngời!\n; # giống nh in xin chào mọi ngời!\n
Trong trờng hợp này, thông báo bắt đầu với Khoản mục kết thúc sẽ ghi lên tớc hiệu
tệp LOGFILE, mà giả thiết là đã mở trớc đây trong chơng trình. Và xin chào mọi ngời
sẽ đi ra lối ra chuẩn, hệt nh khi bạn không xác định tớc hiệu tệp. Chúng ta nói rằng
STDOUT là tớc hiệu xử lí tệp ngầm định cho câu lệnh print.
Vậy, tóm lại, sau đây là cách để sao chép tất cả văn bản từ một tệp đợc xác định
trong $a vào một tệp đợc xác định trong $b. Nó minh hoạ gần nh mọi thứ mà ta đã
học trong vài trang vừa qua:
open (IN,$a) || die không thể mở đợc $a để đọc;
open (OUT, >$b) || die không thể tạo dợc $b;
while (<IN>) { # đọc một dòng từ tệp $a vào $_
print OUT $_; # in dòng đó vào tệp $b
}
close(IN);
close(OUT);
Kiểm tra tệp -x
Bây giờ bạn đã biết cách để mở một tớc hiệu tệp để ghi ra, viết đè lên bất kì tệp
hiện có nào với cùng tên. Giả sử bạn muốn chắc chắn rằng không có một tệp nào với
tên đó (để giữ cho bạn khỏi ngẫu nhiên làm mất tiêu dữ liệu bảng tính hay lịch ngày
sinh quan trọng). Nếu bạn định viết một bản ghi vỏ thì bạn nên dùng cái gì đó tựa nh
-e tên tệp để kiểm tra liệu tệp đó có tồn tại hay không. Tơng tự thế, Perl dùng -e
$filevar để kiểm tra sự tồn tại của tệp mang tên bởi giá trị vô hớng $filevar. Nếu tệp này
tồn tại thì kết quả là đúng; ngợc lại nó là sai. Chẳng hạn:

$x = /etc/passwd;
if (-e $x) { # liệu /etc/passwd có tồn tại không?
# tốt
} else {
print how in the world did you get logged in?\n;
}
Toán hạng của toán tử -e thực sự là bất kì biểu thức vô hớng nào tính một xâu nào
đó, kể cả một xâu hằng. Sau đây là một thí dụ kiểm tra cho cả mật hiệu hệ thống và
tệp nhóm:
if (-e /etc/passwd && -e /etc/group) {
print looks like you have a normal system\n;
Các toán tử khác cũng đợc xác định rõ. Chẳng hạn, -r $filevar cho lại giá trị đúng
nếu tệp đãcó tên trong $filevar đang tồn tại và đọc đợc. Tơng tự, -w $filevar kiểm tra
xem liệu có ghi đợc đợc không. Sau đây là một thí dụ kiểm tra tên tệp do ngời dùng
xác định cho cả tính đọc đợc và ghi đợc:
print ở đâu? ;
$filename = <STDIN>;
chop($filename); # quẳng cái dấu dòng mới khó chịu đi
if (-r $filename && -w $filename) {
# tệp đ có, và tôi có thể đọc và ghi nóã
...
}
Nhiều việc kiểm tra tệp đãcó sẵn. Xin xem Bảng 10-1 để biết danh sách đầy đủ.
Bảng 10.1: Kiểm tra tệp và ý nghĩa của chúng
Kiểm
tra tệp
ý nghĩa
-r
Tệp hay danh mục đọc đợc
-w

Tệp hay danh mục ghi đợc
-x
Tệp hay danh mục thực hiện đợc
-o
Tệp hay danh mục do ngời dùng sở hữu
-R
Tệp hay danh mục đọc đợc bởi ngời dùng thực,
không phải ngời dùng hiệu quả (khác -r với chơng
trình setuid)
-W
Tệp hay danh mục ghi đợc bởi ngời dùng thực,
không phải ngời dùng hiệu quả (khác với -w cho ch-
ơng trình setuid)
-X
Tệp hay danh mục thực hiện đợc bởi ngời dùng
thực, không phải ngời dùng hiệu quả (khác với -x
cho chơng trình setuid)
-O
Tệp hay danh mục đợc sở hữu bởi ngời dùng thực,
không phải ngời dùng hiệu quả (khác với -o cho ch-
ơng trình setuid)
-e
Tệp hay danh mục đã có
-z
Tệp đã có và có kích thớc không (danh mục thì
không bao giờ rỗng)
-s
Tệp hay danh mục đã có và có kích thớc khác
không (giá trị đợc tính theo byte)
-f

Khoản mục là tệp rõ
-d
Khoản mục là danh mục
-l
Khoản mục là symlink
-S
Khoản mục là chỗ cắm
-p
Khoản mục là đờng ống có tên (một fifo)
-b
Khoản mục là tệp khối đặc biệt (giống nh đĩa tháo
lắp đợc)
-c
Khoản mục là tệp kí tự đặc biệt (nh thiết bị vào/ra)
-u
Tệp hay danh mục là setuid
-g
Tệp hay danh mục là setgid
-k
Tệp hay danh mục có tập bit dính
-t
isatty() trên tớc hiệu tệp là đúng
-T
Tệp là văn bản
-B
Tệp là nhị phân
-M
sửa tuổi theo ngày
-A
Tuổi thâm nhập theo ngày

-C
Tuổi thay đổi inode theo ngày
Phần lớn trong những phép kiểm tra này đều cho lại một điều kiện đúng-sai đơn

×