Perl 使用一種稱為檔案句柄類型的變數來操作檔案。
從檔案讀取或寫入資料需要使用檔案句柄。
檔案句柄(file handle)是一個I/O連線的名稱。
Perl提供了三種檔案句柄:STDIN,STDOUT,STDERR,分別代表標準輸入、標準輸出、標準出錯輸出。
Perl 中開啟檔案可以使用以下方式:
open FILEHANDLE, EXPRopen FILEHANDLEsysopen FILEHANDLE, FILENAME, MODE, PERMSsysopen FILEHANDLE, FILENAME, MODE
參數說明:
FILEHANDLE:文件句柄,用來存放一個文件唯一識別碼。
EXPR:檔案名稱及檔案存取類型所組成的表達式。
MODE:檔案存取類型。
PERMS:存取權位元(permission bits)。
以下程式碼我們使用open 函數以唯讀的方式(<)開啟檔案file.txt:
open(DATA, "<file.txt");
<表示唯讀方式。
程式碼中的DATA 為文件句柄用於讀取文件,以下實例將開啟文件並將文件內容輸出:
以下程式碼以寫入( > )的方式開啟檔案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函數類似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 FILEHANDLEclose
FILEHANDLE 為指定的檔案句柄,如果成功關閉則傳回true。
close(DATA) || die "無法關閉檔案";
向文件讀寫資訊有以下幾種不同的方式:
從開啟的檔案句柄讀取資訊的主要方法是<FILEHANDLE> 操作符。在標量上下文中,它從檔案句柄傳回單一行。例如:
當我們使用<FILEHANDLE> 運算元時,它會傳回檔案句柄中每一行的列表,例如我們可以匯入所有的行到數組中。
實作建立import.txt 文件,內容如下:
$ cat import.txt 123
讀取import.txt 並將每一行放到@lines 陣列中:
執行以上程序,輸出結果為:
123
xgetc 函數從指定的FILEHANDLE 傳回單一的字符,如果沒指定回傳STDIN:
getc FILEHANDLEgetc
如果發生錯誤,或在檔案句柄在檔案結尾,則傳回undef。
read 函數用於從緩衝區的檔案句柄讀取資訊。
這個函數用於從檔案讀取二進位資料。
read FILEHANDLE, SCALAR, LENGTH, OFFSETread FILEHANDLE, SCALAR, LENGTH
參數說明:
FILEHANDLE:文件句柄,用來存放一個文件唯一識別碼。
SCALAR:存貯結果,如果沒有指定OFFSET,資料將放在SCALAR的開頭。否則資料放在SCALAR中的OFFSET位元組之後。
LENGTH:讀取的內容長度。
OFFSET:偏移量。
如果讀取成功傳回讀取的位元組數,如果在檔案結尾回傳0,如果發生錯誤回傳undef。
對於所有從檔案句柄中讀取資訊的函數,在後端主要的寫入函數為print:
print FILEHANDLE LISTprint LISTprint
利用檔案句柄和print 函數可以把程式運行的結果發給輸出設備(STDOUT:標準輸出),例如:
print "Hello World!n";
以下實例我們將開啟一個已存在的檔案file1.txt ,並讀取它的每一行寫入到檔案file2.txt 中:
以下實例,我們將已存在的檔案file1.txt 重新命名為file2.txt,指定的目錄是在/usr/codercto/test/ 下:
#!/usr/bin/perlrename ("/usr/codercto/test/file1.txt", "/usr/codercto/test/file2.txt" );函數renames只接受兩個參數,只對已存在的檔案進行重新命名。
以下實例我們示範如何使用unlink函數來刪除檔案:
你可以使用tell函數來取得檔案的位置,並透過使用seek函數來指定檔案內的位置:
tell 函數用於取得檔案位置:
tell FILEHANDLEtell
如果指定FILEHANDLE 此函數傳回檔案指標的位置,以位元組計。如果沒有指定則傳回預設選取的檔案句柄。
seek()函數是透過檔案句柄來移動檔案讀寫指標的方式來讀取或寫入檔案的,以位元組為單位進行讀取和寫入:
seek FILEHANDLE, POSITION, WHENCE
參數說明:
FILEHANDLE:文件句柄,用來存放一個文件唯一識別碼。
POSITION:表示檔案句柄(讀寫位置指標)要移動的位元組數。
WHENCE:表示檔案句柄(讀寫位置指標)開始移動時的起始位置,可以取的值為0、1、2;分別表示檔案開頭、目前位置、檔案尾。
以下實例為從檔案開頭讀取256 個位元組:
seek DATA, 256, 0;
Perl 的檔案操作也可以先測試檔案是否存在,是否可讀寫等。
我們可以先建立file1.txt 文件,內如如下:
$ cat file1.txt www.codercto.com
執行以上程序,輸出結果為:
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),即是否為空文件, |