Perl 檔案操作

Perl 檔案操作

Perl 使用一種叫做檔案控制代碼型別的變數來操作檔案。

從檔案讀取或者寫入資料需要使用檔案控制代碼。

檔案控制代碼(file handle)是一個I/O連線的名稱。

Perl提供了三種檔案控制代碼:STDIN,STDOUT,STDERR,分別代表標準輸入、標準輸出和標準出錯輸出。

Perl 中開啟檔案可以使用以下方式:

open FILEHANDLE, EXPR
open FILEHANDLE

sysopen FILEHANDLE, FILENAME, MODE, PERMS
sysopen FILEHANDLE, FILENAME, MODE

引數說明:

  • FILEHANDLE:檔案控制代碼,用於存放一個檔案唯一識別符號。
  • EXPR:檔名及檔案訪問型別組成的表示式。
  • MODE:檔案訪問型別。
  • PERMS:訪問許可權位(permission bits)。

Open 函式

以下程式碼我們使用 open 函式以只讀的方式(<)開啟檔案 file.txt:

open(DATA, "<file.txt");

<表示只讀方式。

程式碼中的 DATA 為檔案控制代碼用於讀取檔案,以下例項將開啟檔案並將檔案內容輸出:

例項

#!/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 檔案無法開啟, $!";

這種方式不會刪除檔案原來的內容,如果要刪除,格式如下所示:

open DATA, "+>file.txt" or die "file.txt 檔案無法開啟, $!";

如果要向檔案中追加資料,則在追加資料之前,只需要以追加方式開啟檔案即可:

open(DATA,">>file.txt") || die "file.txt 檔案無法開啟, $!";

>> 表示向現有檔案的尾部追加資料,如果需要讀取要追加的檔案內容可以新增 + 號:

open(DATA,"+>>file.txt") || die "file.txt 檔案無法開啟, $!";

下表列出了不同的訪問模式:

模式描述
< 或 r只讀方式開啟,將檔案指標指向檔案頭。
> 或 w寫入方式開啟,將檔案指標指向檔案頭並將檔案大小截為零。如果檔案不存在則嘗試建立之。
>> 或 a寫入方式開啟,將檔案指標指向檔案末尾。如果檔案不存在則嘗試建立之。
+< 或 r+讀寫方式開啟,將檔案指標指向檔案頭。
+> 或 w+讀寫方式開啟,將檔案指標指向檔案頭並將檔案大小截為零。如果檔案不存在則嘗試建立之。
+>> 或 a+讀寫方式開啟,將檔案指標指向檔案末尾。如果檔案不存在則嘗試建立之。

Sysopen函式

sysopen 函式類似於 open 函式,只是它們的引數形式不一樣。

以下例項是以讀寫(+<filename)的方式開啟檔案:

sysopen(DATA, "file.txt", O_RDWR);

如果需要在更新檔案前清空檔案,則寫法如下:

sysopen(DATA, "file.txt", O_RDWR|O_TRUNC );

你可以使用 O_CREAT 來建立一個新的檔案, O_WRONLY 為只寫模式, O_RDONLY 為只讀模式。

The PERMS 引數為八進位制屬性值,表示檔案建立後的許可權,預設為 0x666

下表列出了可能的模式值:

模式描述
O_RDWR讀寫方式開啟,將檔案指標指向檔案頭。
O_RDONLY只讀方式開啟,將檔案指標指向檔案頭。
O_WRONLY寫入方式開啟,將檔案指標指向檔案頭並將檔案大小截為零。如果檔案不存在則嘗試建立之。
O_CREAT建立檔案
O_APPEND追加檔案
O_TRUNC將檔案大小截為零
O_EXCL 如果使用O_CREAT時檔案存在,就返回錯誤資訊,它可以測試檔案是否存在
O_NONBLOCK 非阻塞I/O使我們的操作要麼成功,要麼立即返回錯誤,不被阻塞。

Close 函式

在檔案使用完後,要關閉檔案,以重新整理與檔案控制代碼相關聯的輸入輸出緩衝區,關閉檔案的語法如下:

close FILEHANDLE
close

FILEHANDLE 為指定的檔案控制代碼,如果成功關閉則返回 true。

close(DATA) || die "無法關閉檔案";

讀寫檔案

向檔案讀寫資訊有以下幾種不同的方式:

<FILEHANDL> 操作符

從開啟的檔案控制代碼讀取資訊的主要方法是 <FILEHANDLE> 操作符。在標量上下文中,它從檔案控制代碼返回單一行。例如:

例項

#!/usr/bin/perl print "入門教學網址?\n"; $name = <STDIN>; print "網址:$name\n";

以上程式執行後,會顯示以下資訊,我們輸入網址後 print 語句就會輸出:

當我們使用 <FILEHANDLE> 操作符時,它會返回檔案控制代碼中每一行的列表,例如我們可以匯入所有的行到陣列中。

實現建立 import.txt 檔案,內容如下:

$ cat import.txt 
1
2
3

讀取 import.txt 並將每一行放到 @lines 陣列中:

例項

#!/usr/bin/perl open(DATA,"<import.txt") or die "無法開啟資料"; @lines = <DATA>; print @lines; # 輸出陣列內容 close(DATA);

執行以上程式,輸出結果為:

1
2
3

getc 函式

xgetc 函式從指定的 FILEHANDLE 返回單一的字元,如果沒指定返回 STDIN:

getc FILEHANDLE
getc

如果發生錯誤,或在檔案控制代碼在檔案末尾,則返回 undef。


read 函式

read 函式用於從緩衝區的檔案控制代碼讀取資訊。

這個函式用於從檔案讀取二進位制資料。

read FILEHANDLE, SCALAR, LENGTH, OFFSET
read FILEHANDLE, SCALAR, LENGTH

引數說明:

  • FILEHANDLE:檔案控制代碼,用於存放一個檔案唯一識別符號。
  • SCALAR:存貯結果,如果沒有指定OFFSET,資料將放在SCALAR的開頭。否則資料放在SCALAR中的OFFSET位元組之後。
  • LENGTH:讀取的內容長度。
  • OFFSET:偏移量。

如果讀取成功返回讀取的位元組數,如果在檔案結尾返回 0,如果發生錯誤返回 undef。

print 函式

對於所有從檔案控制代碼中讀取資訊的函式,在後端主要的寫入函式為 print:

print FILEHANDLE LIST
print LIST
print

利用檔案控制代碼和 print 函式可以把程式執行的結果發給輸出裝置(STDOUT:標準輸出),例如:

print "Hello World!\n";

檔案拷貝

以下例項我們將開啟一個已存在的檔案 file1.txt ,並讀取它的每一行寫入到檔案 file2.txt 中:

例項

#!/usr/bin/perl # 只讀方式開啟檔案 open(DATA1, "<file1.txt"); # 開啟新檔案並寫入 open(DATA2, ">file2.txt"); # 拷貝資料 while(<DATA1>) { print DATA2 $_; } close( DATA1 ); close( DATA2 );

檔案重新命名

以下例項,我們將已存在的檔案 file1.txt 重新命名為 file2.txt,指定的目錄是在 /usr/itread01/test/ 下:

#!/usr/bin/perl

rename ("/usr/itread01/test/file1.txt", "/usr/itread01/test/file2.txt" );

函式 renames 只接受兩個引數,只對已存在的檔案進行重新命名。

刪除檔案

以下例項我們演示瞭如何使用 unlink 函式來刪除檔案:

例項

#!/usr/bin/perl unlink ("/usr/itread01/test/file1.txt");

指定檔案位置

你可以使用 tell 函式來獲取檔案的位置,並通過使用 seek 函式來指定檔案內的的位置:

tell 函式

tell 函式用於獲取檔案位置:

tell FILEHANDLE
tell

如果指定 FILEHANDLE 該函式返回檔案指標的位置,以位元組計。如果沒有指定則返回預設選取的檔案控制代碼。

seek 函式

seek()函式是通過檔案控制代碼來移動檔案讀寫指標的方式來讀取或寫入檔案的,以位元組為單位進行讀取和寫入:

seek FILEHANDLE, POSITION, WHENCE

引數說明:

  • FILEHANDLE:檔案控制代碼,用於存放一個檔案唯一識別符號。
  • POSITION:表示檔案控制代碼(讀寫位置指標)要移動的位元組數。
  • WHENCE:表示檔案控制代碼(讀寫位置指標)開始移動時的起始位置,可以取的值為0、1、2;分別表示檔案開頭、當前位置和檔案尾。

以下例項為從檔案開頭讀取 256 個位元組:

seek DATA, 256, 0;

檔案資訊

Perl 的檔案操作也可以先測試檔案是否存在,是否可讀寫等。

我們可以先建立 file1.txt 檔案,內如如下:

$ cat file1.txt 
www.itread01.com

例項

#/usr/bin/perl my $file = "/usr/test/itread01/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 位元組" : ''; print "$file 資訊:", join(', ',@description),"\n"; }

執行以上程式,輸出結果為:

file1.txt 資訊:是一個文字檔案, 15 位元組

檔案測試操作符如下表所示:

操作符描述
-A檔案上一次被訪問的時間(單位:天)
-B 是否為二進位制檔案
-C 檔案的(inode)索引節點修改時間(單位:天)
-M 檔案上一次被修改的時間(單位:天)
-O 檔案被真實的UID所有
-R 檔案或目錄可以被真實的UID/GID讀取
-S 為socket(套接字)
-T 是否為文字檔案
-W 檔案或目錄可以被真實的UID/GID寫入
-X 檔案或目錄可以被真實的UID/GID執行
-b 為block-special (特殊塊)檔案(如掛載磁碟)
-c 為character-special (特殊字元)檔案(如I/O 裝置)
-d 為目錄
-e 檔案或目錄名存在
-f 為普通檔案
-g 檔案或目錄具有setgid屬性
-k 檔案或目錄設定了sticky位
-l 為符號連結
-o 檔案被有效UID所有
-p 檔案是命名管道(FIFO)
-r 檔案可以被有效的UID/GID讀取
-s 檔案或目錄存在且不為0(返回位元組數)
-t 檔案控制代碼為TTY(系統函式isatty()的返回結果;不能對檔名使用這個測試)
-u 檔案或目錄具有setuid屬性
-w 檔案可以被有效的UID/GID寫入
-x 檔案可以被有效的UID/GID執行
-z檔案存在,大小為0(目錄恆為false),即是否為空檔案,