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 "php中文网网址?\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:開始讀取位置。

  • 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/php/test/ 下:

#!/usr/bin/perl

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

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

刪除檔案

以下實例我們示範如何使用unlink 函數來刪除檔案:

#!/usr/bin/perl

unlink ("/usr/php/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.php.cn
#/usr/bin/perl

my $file = "/usr/test/php/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 字节

檔案測試運算子如下表所示:

##為普通檔案-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),即是否為空文件,
運算子描述
#-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