Perl 文件操作
Perl 使用一種叫做文件句柄類型的變量來操作文件。
從文件讀取或者寫入數(shù)據(jù)需要使用文件句柄。
文件句柄(file handle)是一個I/O連接的名稱。
Perl提供了三種文件句柄:STDIN,STDOUT,STDERR,分別代表標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)出錯輸出。
Perl 中打開文件可以使用以下方式:
open FILEHANDLE, EXPR open FILEHANDLE sysopen FILEHANDLE, FILENAME, MODE, PERMS sysopen FILEHANDLE, FILENAME, MODE
參數(shù)說明:
- FILEHANDLE:文件句柄,用于存放一個文件唯一標(biāo)識符。
- EXPR:文件名及文件訪問類型組成的表達式。
- MODE:文件訪問類型。
- PERMS:訪問權(quán)限位(permission bits)。
Open 函數(shù)
以下代碼我們使用 open 函數(shù)以只讀的方式(<)打開文件 file.txt:
open(DATA, "<file.txt");
<表示只讀方式。
代碼中的 DATA 為文件句柄用于讀取文件,以下實例將打開文件并將文件內(nèi)容輸出:
#!/usr/bin/perl open(DATA, "<file.txt") or die "file.txt 文件無法打開, $!"; while(<DATA>){ print "$_"; }
以下代碼以寫入( > )的方式打開文件 file.txt:
open(DATA, ">file.txt") or die "file.txt 文件無法打開, $!";
>表示寫入方式。
如果你需要以讀寫方式打開文件,可以在 > 或 < 字符前添加 + 號:
open(DATA, "+<file.txt"); or die "file.txt 文件無法打開, $!";
這種方式不會刪除文件原來的內(nèi)容,如果要刪除,格式如下所示:
open DATA, "+>file.txt" or die "file.txt 文件無法打開, $!";
如果要向文件中追加數(shù)據(jù),則在追加數(shù)據(jù)之前,只需要以追加方式打開文件即可:
open(DATA,">>file.txt") || die "file.txt 文件無法打開, $!";
>> 表示向現(xiàn)有文件的尾部追加數(shù)據(jù),如果需要讀取要追加的文件內(nèi)容可以添加 + 號:
open(DATA,"+>>file.txt") || die "file.txt 文件無法打開, $!";
下表列出了不同的訪問模式:
模式 | 描述 |
---|---|
< 或 r | 只讀方式打開,將文件指針指向文件頭。 |
> 或 w | 寫入方式打開,將文件指針指向文件頭并將文件大小截為零。如果文件不存在則嘗試創(chuàng)建之。 |
>> 或 a | 寫入方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創(chuàng)建之。 |
+< 或 r+ | 讀寫方式打開,將文件指針指向文件頭。 |
+> 或 w+ | 讀寫方式打開,將文件指針指向文件頭并將文件大小截為零。如果文件不存在則嘗試創(chuàng)建之。 |
+>> 或 a+ | 讀寫方式打開,將文件指針指向文件末尾。如果文件不存在則嘗試創(chuàng)建之。 |
Sysopen函數(shù)
sysopen 函數(shù)類似于 open 函數(shù),只是它們的參數(shù)形式不一樣。
以下實例是以讀寫(+<filename)的方式打開文件:
sysopen(DATA, "file.txt", O_RDWR);
如果需要在更新文件前清空文件,則寫法如下:
sysopen(DATA, "file.txt", O_RDWR|O_TRUNC );
你可以使用 O_CREAT 來創(chuàng)建一個新的文件, O_WRONLY 為只寫模式, O_RDONLY 為只讀模式。
The PERMS 參數(shù)為八進制屬性值,表示文件創(chuàng)建后的權(quán)限,默認(rèn)為 0x666。
下表列出了可能的模式值:
模式 | 描述 |
---|---|
O_RDWR | 讀寫方式打開,將文件指針指向文件頭。 |
O_RDONLY | 只讀方式打開,將文件指針指向文件頭。 |
O_WRONLY | 寫入方式打開,將文件指針指向文件頭并將文件大小截為零。如果文件不存在則嘗試創(chuàng)建之。 |
O_CREAT | 創(chuàng)建文件 |
O_APPEND | 追加文件 |
O_TRUNC | 將文件大小截為零 |
O_EXCL | 如果使用O_CREAT時文件存在,就返回錯誤信息,它可以測試文件是否存在 |
O_NONBLOCK | 非阻塞I/O使我們的操作要么成功,要么立即返回錯誤,不被阻塞。 |
Close 函數(shù)
在文件使用完后,要關(guān)閉文件,以刷新與文件句柄相關(guān)聯(lián)的輸入輸出緩沖區(qū),關(guān)閉文件的語法如下:
close FILEHANDLE close
FILEHANDLE 為指定的文件句柄,如果成功關(guān)閉則返回 true。
close(DATA) || die "無法關(guān)閉文件";
讀寫文件
向文件讀寫信息有以下幾種不同的方式:
<FILEHANDL> 操作符
從打開的文件句柄讀取信息的主要方法是 <FILEHANDLE> 操作符。在標(biāo)量上下文中,它從文件句柄返回單一行。例如:
#!/usr/bin/perl print "W3Cschool教程網(wǎng)址?\n"; $name = <STDIN>; print "網(wǎng)址:$name\n";
以上程序執(zhí)行后,會顯示以下信息,我們輸入網(wǎng)址后 print 語句就會輸出:
當(dāng)我們使用 <FILEHANDLE> 操作符時,它會返回文件句柄中每一行的列表,例如我們可以導(dǎo)入所有的行到數(shù)組中。
實現(xiàn)創(chuàng)建 import.txt 文件,內(nèi)容如下:
$ cat import.txt 1 2 3
讀取 import.txt 并將每一行放到 @lines 數(shù)組中:
#!/usr/bin/perl open(DATA,"<import.txt") or die "無法打開數(shù)據(jù)"; @lines = <DATA>; print @lines; # 輸出數(shù)組內(nèi)容 close(DATA);
執(zhí)行以上程序,輸出結(jié)果為:
1 2 3
getc 函數(shù)
xgetc 函數(shù)從指定的 FILEHANDLE 返回單一的字符,如果沒指定返回 STDIN:
getc FILEHANDLE getc
如果發(fā)生錯誤,或在文件句柄在文件末尾,則返回 undef。
read 函數(shù)
read 函數(shù)用于從緩沖區(qū)的文件句柄讀取信息。
這個函數(shù)用于從文件讀取二進制數(shù)據(jù)。
read FILEHANDLE, SCALAR, LENGTH, OFFSET read FILEHANDLE, SCALAR, LENGTH
參數(shù)說明:
- FILEHANDLE:文件句柄,用于存放一個文件唯一標(biāo)識符。
- SCALAR:存貯結(jié)果,如果沒有指定OFFSET,數(shù)據(jù)將放在SCALAR的開頭。否則數(shù)據(jù)放在SCALAR中的OFFSET字節(jié)之后。
- LENGTH:讀取的內(nèi)容長度。
- OFFSET:偏移量。
如果讀取成功返回讀取的字節(jié)數(shù),如果在文件結(jié)尾返回 0,如果發(fā)生錯誤返回 undef。
print 函數(shù)
對于所有從文件句柄中讀取信息的函數(shù),在后端主要的寫入函數(shù)為 print:
print FILEHANDLE LIST print LIST print
利用文件句柄和 print 函數(shù)可以把程序運行的結(jié)果發(fā)給輸出設(shè)備(STDOUT:標(biāo)準(zhǔn)輸出),例如:
print "Hello World!\n";
文件拷貝
以下實例我們將打開一個已存在的文件 file1.txt ,并讀取它的每一行寫入到文件 file2.txt 中:
#!/usr/bin/perl # 只讀方式打開文件 open(DATA1, "<file1.txt"); # 打開新文件并寫入 open(DATA2, ">file2.txt"); # 拷貝數(shù)據(jù) while(<DATA1>) { print DATA2 $_; } close( DATA1 ); close( DATA2 );
文件重命名
以下實例,我們將已存在的文件 file1.txt 重命名為 file2.txt,指定的目錄是在 /usr/youj/test/ 下:
#!/usr/bin/perl rename ("/usr/youj/test/file1.txt", "/usr/youj/test/file2.txt" );
函數(shù) renames 只接受兩個參數(shù),只對已存在的文件進行重命名。
刪除文件
以下實例我們演示了如何使用 unlink 函數(shù)來刪除文件:
#!/usr/bin/perl unlink ("/usr/youj/test/file1.txt");
指定文件位置
你可以使用 tell 函數(shù)來獲取文件的位置,并通過使用 seek 函數(shù)來指定文件內(nèi)的的位置:
tell 函數(shù)
tell 函數(shù)用于獲取文件位置:
tell FILEHANDLE tell
如果指定 FILEHANDLE 該函數(shù)返回文件指針的位置,以字節(jié)計。如果沒有指定則返回默認(rèn)選取的文件句柄。
seek 函數(shù)
seek()函數(shù)是通過文件句柄來移動文件讀寫指針的方式來讀取或?qū)懭胛募模宰止?jié)為單位進行讀取和寫入:
seek FILEHANDLE, POSITION, WHENCE
參數(shù)說明:
- FILEHANDLE:文件句柄,用于存放一個文件唯一標(biāo)識符。
- POSITION:表示文件句柄(讀寫位置指針)要移動的字節(jié)數(shù)。
- WHENCE:表示文件句柄(讀寫位置指針)開始移動時的起始位置,可以取的值為0、1、2;分別表示文件開頭、當(dāng)前位置和文件尾。
以下實例為從文件開頭讀取 256 個字節(jié):
seek DATA, 256, 0;
文件信息
Perl 的文件操作也可以先測試文件是否存在,是否可讀寫等。
我么可以先創(chuàng)建 file1.txt 文件,內(nèi)如如下:
$ cat file1.txt m.hgci.cn
#/usr/bin/perl my $file = "/usr/test/youj/file1.txt"; my (@description, $size); if (-e $file) { push @description, '是一個二進制文件' if (-B _); push @description, '是一個socket(套接字)' if (-S _); push @description, '是一個文本文件' if (-T _); push @description, '是一個特殊塊文件' if (-b _); push @description, '是一個特殊字符文件' if (-c _); push @description, '是一個目錄' if (-d _); push @description, '文件存在' if (-x _); push @description, (($size = -s _)) ? "$size 字節(jié)" : '空'; print "$file 信息:", join(', ',@description),"\n"; }
執(zhí)行以上程序,輸出結(jié)果為:
file1.txt 信息:是一個文本文件, 15 字節(jié)
文件測試操作符如下表所示:
操作符 | 描述 |
---|---|
-A | 文件上一次被訪問的時間(單位:天) |
-B | 是否為二進制文件 |
-C | 文件的(inode)索引節(jié)點修改時間(單位:天) |
-M | 文件上一次被修改的時間(單位:天) |
-O | 文件被真實的UID所有 |
-R | 文件或目錄可以被真實的UID/GID讀取 |
-S | 為socket(套接字) |
-T | 是否為文本文件 |
-W | 文件或目錄可以被真實的UID/GID寫入 |
-X | 文件或目錄可以被真實的UID/GID執(zhí)行 |
-b | 為block-special (特殊塊)文件(如掛載磁盤) |
-c | 為character-special (特殊字符)文件(如I/O 設(shè)備) |
-d | 為目錄 |
-e | 文件或目錄名存在 |
-f | 為普通文件 |
-g | 文件或目錄具有setgid屬性 |
-k | 文件或目錄設(shè)置了sticky位 |
-l | 為符號鏈接 |
-o | 文件被有效UID所有 |
-p | 文件是命名管道(FIFO) |
-r | 文件可以被有效的UID/GID讀取 |
-s | 文件或目錄存在且不為0(返回字節(jié)數(shù)) |
-t | 文件句柄為TTY(系統(tǒng)函數(shù)isatty()的返回結(jié)果;不能對文件名使用這個測試) |
-u | 文件或目錄具有setuid屬性 |
-w | 文件可以被有效的UID/GID寫入 |
-x | 文件可以被有效的UID/GID執(zhí)行 |
-z | 文件存在,大小為0(目錄恒為false),即是否為空文件, |
更多建議: