Perl - 文件 I/O


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

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

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

打开和关闭文件

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

open FILEHANDLE, EXPR
open FILEHANDLE

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

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

开放功能

以下是以只读模式打开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

>> 或一个

写入、追加和创建

4

+< 或 r+

读取和写入

5

+> 或 w+

读取、写入、创建和截断

6

+>> 或 a+

读取、写入、追加和创建

系统开放功能

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_非阻塞

非阻塞可用性

关闭功能

要关闭文件句柄,从而取消文件句柄与相应文件的关联,请使用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 函数从指定的 FILEHANDLE 返回单个字符,如果未指定,则返回 STDIN -

getc FILEHANDLE
getc

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

读取功能

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

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

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

打印功能

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

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" );

此函数重命名需要两个参数,它只是重命名现有文件。

删除现有文件

下面是一个示例,显示如何使用unlink函数删除文件 file1.txt。

#!/usr/bin/perl

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

在文件内定位

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

告诉函数

第一个要求是找到您在文件中的位置,您可以使用tell函数来完成此操作 -

tell FILEHANDLE
tell

如果指定,则返回文件指针在 FILEHANDLE 中的位置(以字节为单位);如果未指定,则返回当前默认选择的文件句柄。

查找函数

查找函数将文件指针定位到文件中指定的字节数 -

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

文件大小是否为零?