Perl - 文件 I/O



文件处理的基础知识很简单:你将一个文件句柄与外部实体(通常是文件)关联起来,然后使用Perl中的各种运算符和函数来读取和更新与文件句柄关联的数据流中存储的数据。

文件句柄是Perl内部命名的结构,它将物理文件与名称关联起来。所有文件句柄都能够进行读/写访问,因此您可以读取和更新与文件句柄关联的任何文件或设备。但是,当您关联文件句柄时,您可以指定打开文件句柄的模式。

三个基本文件句柄是 - STDINSTDOUTSTDERR,它们分别代表标准输入、标准输出和标准错误设备。

打开和关闭文件

Perl中可以使用以下两个具有多种形式的函数来打开任何新的或现有的文件。

open FILEHANDLE, EXPR
open FILEHANDLE

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

这里FILEHANDLE是由open函数返回的文件句柄,EXPR是包含文件名和打开文件模式的表达式。

Open 函数

以下是以只读模式打开file.txt的语法。这里的小于号<表示文件必须以只读模式打开。

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

这里DATA是文件句柄,将用于读取文件。这是一个示例,它将打开一个文件并将内容打印到屏幕上。

#!/usr/bin/perl

open(DATA, "<file.txt") or die "Couldn't open file file.txt, $!";

while(<DATA>) {
   print "$_";
}

以下是以写入模式打开file.txt的语法。这里大于号>表示文件必须以写入模式打开。

open(DATA, ">file.txt") or die "Couldn't open file file.txt, $!";

此示例实际上在打开文件进行写入之前会截断(清空)文件,这可能不是预期的效果。如果要打开文件进行读取和写入,可以在>或<字符前面加上加号。

例如,要打开文件进行更新而不截断它:

open(DATA, "+<file.txt"); or die "Couldn't open file file.txt, $!";

要先截断文件:

open DATA, "+>file.txt" or die "Couldn't open file file.txt, $!";

您可以以追加模式打开文件。在此模式下,写入点将设置为文件的末尾。

open(DATA,">>file.txt") || die "Couldn't open file file.txt, $!";

双>>以追加模式打开文件,将文件指针放在末尾,以便您可以立即开始追加信息。但是,除非您还在其前面加上加号,否则无法从中读取:

open(DATA,"+>>file.txt") || die "Couldn't open file file.txt, $!";

下表列出了不同模式的可能值

序号 实体和定义
1

< 或 r

只读访问

2

> 或 w

创建、写入和截断

3

>> 或 a

写入、追加和创建

4

+< 或 r+

读取和写入

5

+> 或 w+

读取、写入、创建和截断

6

+>> 或 a+

读取、写入、追加和创建

Sysopen 函数

sysopen函数类似于主要的open函数,不同之处在于它使用系统open()函数,使用提供的参数作为系统函数的参数:

例如,要打开文件进行更新,模拟open中的+<filename格式:

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

或者在更新前截断文件:

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

您可以使用O_CREAT创建新文件,使用O_WRONLY以只写模式打开文件,使用O_RDONLY以只读模式打开文件。

如果必须创建PERMS参数,则指定文件的权限。默认情况下,它采用0x666

下表列出了MODE的可能值。

序号 实体和定义
1

O_RDWR

读写

2

O_RDONLY

只读

3

O_WRONLY

只写

4

O_CREAT

创建文件

5

O_APPEND

追加到文件

6

O_TRUNC

截断文件

7

O_EXCL

如果文件已存在则停止

8

O_NONBLOCK

非阻塞可用性

Close 函数

要关闭文件句柄,从而取消文件句柄与相应文件的关联,可以使用close函数。这将刷新文件句柄的缓冲区并关闭系统的文件描述符。

close FILEHANDLE
close

如果没有指定FILEHANDLE,则它将关闭当前选择的文件句柄。只有在成功刷新缓冲区并关闭文件时,它才返回true。

close(DATA) || die "Couldn't close file properly";

读取和写入文件

打开文件句柄后,您需要能够读取和写入信息。有多种不同的方法可以将数据读入和写入文件。

<FILEHANDL> 运算符

从打开的文件句柄读取信息的主要方法是<FILEHANDLE>运算符。在标量上下文中,它从文件句柄返回一行。例如:

#!/usr/bin/perl

print "What is your name?\n";
$name = <STDIN>;
print "Hello $name\n";

在列表上下文中使用<FILEHANDLE>运算符时,它将返回指定文件句柄中的一行列表。例如,要将文件中的所有行导入到数组中:

#!/usr/bin/perl

open(DATA,"<import.txt") or die "Can't open data";
@lines = <DATA>;
close(DATA);

getc 函数

getc函数从指定FILEHANDLE或STDIN(如果没有指定)返回单个字符:

getc FILEHANDLE
getc

如果发生错误,或者文件句柄位于文件末尾,则返回undef。

read 函数

read函数从缓冲的文件句柄读取一块信息:此函数用于从文件读取二进制数据。

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

读取的数据长度由LENGTH定义,如果未指定OFFSET,则数据将放置在SCALAR的开头。否则,数据将放置在SCALAR中OFFSET字节之后。该函数在成功时返回读取的字节数,在文件末尾返回零,如果发生错误则返回undef。

print 函数

对于用于从文件句柄读取信息的所有不同方法,写入信息的主要函数是print函数。

print FILEHANDLE LIST
print LIST
print

print函数将LIST的计算值打印到FILEHANDLE,或打印到当前输出文件句柄(默认为STDOUT)。例如:

print "Hello World!\n";

复制文件

这是一个示例,它打开一个现有的文件file1.txt并逐行读取它,然后生成另一个副本文件file2.txt。

#!/usr/bin/perl

# Open file to read
open(DATA1, "<file1.txt");

# Open new file to write
open(DATA2, ">file2.txt");

# Copy data from one file to another.
while(<DATA1>) {
   print DATA2 $_;
}
close( DATA1 );
close( DATA2 );

重命名文件

这是一个示例,它演示了如何将文件file1.txt重命名为file2.txt。假设文件位于/usr/test目录中。

#!/usr/bin/perl

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

此函数renames接受两个参数,它只是重命名现有文件。

删除现有文件

这是一个示例,它演示了如何使用unlink函数删除文件file1.txt。

#!/usr/bin/perl

unlink ("/usr/test/file1.txt");

在文件中定位

您可以使用tell函数来了解文件的当前位置,并使用seek函数来指向文件内的特定位置。

tell 函数

第一个要求是在文件中找到您的位置,您可以使用tell函数:

tell FILEHANDLE
tell

如果指定了FILEHANDLE,则返回文件指针在FILEHANDLE中的字节位置;如果没有指定,则返回当前选择的默认文件句柄的位置。

seek 函数

seek函数将文件指针定位到文件内指定的字节数:

seek FILEHANDLE, POSITION, WHENCE

该函数使用fseek系统函数,您可以根据三个不同的点进行定位:开头、结尾和当前位置。您可以通过为WHENCE指定一个值来实现。

零将定位设置为相对于文件的开头。例如,该行将文件指针设置为文件中的第256个字节。

seek DATA, 256, 0;

文件信息

您可以使用一系列统称为-X测试的测试运算符在Perl中快速测试某些功能。例如,要对文件的各种权限进行快速测试,您可以使用这样的脚本:

#/usr/bin/perl

my $file = "/usr/test/file1.txt";
my (@description, $size);
if (-e $file) {
   push @description, 'binary' if (-B _);
   push @description, 'a socket' if (-S _);
   push @description, 'a text file' if (-T _);
   push @description, 'a block special file' if (-b _);
   push @description, 'a character special file' if (-c _);
   push @description, 'a directory' if (-d _);
   push @description, 'executable' if (-x _);
   push @description, (($size = -s _)) ? "$size bytes" : 'empty';
   print "$file is ", join(', ',@description),"\n";
}

以下是您可以为文件或目录检查的功能列表:

序号 运算符和定义
1

-A

脚本启动时间减去文件上次访问时间(以天为单位)。

2

-B

它是二进制文件吗?

3

-C

脚本启动时间减去文件上次inode更改时间(以天为单位)。

3

-M

脚本启动时间减去文件修改时间(以天为单位)。

4

-O

该文件是否由真实用户ID拥有?

5

-R

真实用户ID或真实组是否可以读取该文件?

6

-S

该文件是否是套接字?

7

-T

它是文本文件吗?

8

-W

真实用户ID或真实组是否可以写入该文件?

9

-X

真实用户ID或真实组是否可以执行该文件?

10

-b

它是块特殊文件吗?

11

-c

它是字符特殊文件吗?

12

-d

该文件是目录吗?

13

-e

文件是否存在?

14

-f

它是普通文件吗?

15

-g

该文件是否设置了setgid位?

16

-k

该文件是否设置了粘滞位?

17

-l

该文件是符号链接吗?

18

-o

该文件是否由有效用户ID拥有?

19

-p

该文件是命名管道吗?

20

-r

有效用户或组ID是否可以读取该文件?

21

-s

返回文件大小,零大小=空文件。

22

-t

文件句柄是由TTY(终端)打开的吗?

23

-u

该文件是否设置了setuid位?

24

-w

有效用户或组ID是否可以写入该文件?

25

-x

当前有效用户或用户组ID是否具有该文件的执行权限?

26

-z

文件大小是否为零?

广告