Perl - 文件 I/O
处理文件的基础很简单:将 filehandle 与外部实体(通常是文件)相关联,然后使用 Perl 中的各种运算符和函数来读取和更新存储在数据流中的数据 与文件句柄相关联。
文件句柄是一个命名的内部 Perl 结构,它将物理文件与名称相关联。 所有文件句柄都能够读/写访问,因此您可以读取和更新与文件句柄关联的任何文件或设备。 但是,当您关联文件句柄时,您可以指定打开文件句柄的模式。
三个基本文件句柄是 - STDIN、STDOUT 和 STDERR,它们分别代表标准输入、标准输出和标准错误设备。
打开和关闭文件
有以下两个函数,具有多种形式,可用于在 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, $!";
下表给出了不同 MODE 的可能值
序号 | 实体与定义 |
---|---|
1 | < or r Read Only Access |
2 | > or w Creates, Writes, and Truncates |
3 | >> or a Writes, Appends, and Creates |
4 | +< or r+ Reads and Writes |
5 | +> or w+ Reads, Writes, Creates, and Truncates |
6 | +>> or a+ Reads, Writes, Appends, and Creates |
Sysopen 函数
sysopen 函数类似于 main 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 Read and Write |
2 | O_RDONLY Read Only |
3 | O_WRONLY Write Only |
4 | O_CREAT Create the file |
5 | O_APPEND Append the file |
6 | O_TRUNC Truncate the file |
7 | O_EXCL Stops if file already exists |
8 | O_NONBLOCK Non-Blocking usability |
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 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 中的位置(以字节为单位),如果未指定,则返回当前默认选择的文件句柄。
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 文件大小为零吗? |