#Perl file operations
#Open and close files
#Open file for reading
open(my $fh, '<', 'input.txt') or die "Cannot open file: $!";
while (my $line = <$fh>) {
print $line;
}
close($fh);#Open file for writing
open(my $fh, '>', 'output.txt') or die "Cannot open file: $!";
print $fh "Hello, World!\n";
print $fh "This is a test.\n";
close($fh);#Open file for appending
open(my $fh, '>>', 'log.txt') or die "Cannot open file: $!";
print $fh "Log entry: " . localtime() . "\n";
close($fh);#Open mode summary
| Mode | Description | If the file exists | If the file does not exist |
|---|---|---|---|
< | Read | Read from the beginning | Report error |
> | write | clear and write | create new file |
>> | Append | Append at the end | Create new file |
+< | Read and write | Read and write from the beginning | Report errors |
+> | Read and write | Clear and read and write | Create new file |
+>> | read and write append | read and write | create new file |
#Read file
#Read line by line
open(my $fh, '<', 'data.txt') or die "Cannot open file: $!";
while (my $line = <$fh>) {
chomp $line; # 移除换行符
print "$line\n";
}
close($fh);#Read the entire file into an array
open(my $fh, '<', 'data.txt') or die "Cannot open file: $!";
my @lines = <$fh>; # 读取所有行
close($fh);
foreach my $line (@lines) {
chomp $line;
print "$line\n";
}#Read entire file into scalar
open(my $fh, '<', 'data.txt') or die "Cannot open file: $!";
# 方法 1:使用 local
local $/;
my $content = <$fh>;
close($fh);
print $content;
# 方法 2:使用 File::Slurp
use File::Slurp;
my $content2 = read_file('data.txt');#Read a fixed number of bytes
open(my $fh, '<', 'data.txt') or die "Cannot open file: $!";
my $buffer;
my $bytes_read = read($fh, $buffer, 1024); # 读取 1024 字节
print "Read $bytes_read bytes\n";
print $buffer;
close($fh);#Using sysread and syswrite
open(my $fh, '<', 'data.txt') or die "Cannot open file: $!";
my $buffer;
my $bytes_read = sysread($fh, $buffer, 256);
print "Read $bytes_read bytes using sysread\n";
close($fh);#Write to file
#Write text
open(my $fh, '>', 'output.txt') or die "Cannot open file: $!";
print $fh "Line 1\n";
print $fh "Line 2\n";
print $fh "Line 3\n";
close($fh);#Use say to wrap lines automatically (Perl 5.10+)
use v5.10;
open(my $fh, '>', 'output.txt') or die "Cannot open file: $!";
say $fh "Line 1";
say $fh "Line 2";
say $fh "Line 3";
close($fh);#Formatted writing
open(my $fh, '>', 'report.txt') or die "Cannot open file: $!";
printf $fh "%-20s %10s %10s\n", "Name", "Age", "Score";
printf $fh "%-20s %10d %10d\n", "Alice", 25, 95;
printf $fh "%-20s %10d %10d\n", "Bob", 30, 88;
close($fh);#Use syswrite
open(my $fh, '>', 'output.txt') or die "Cannot open file: $!";
my $data = "Hello, World!";
my $bytes_written = syswrite($fh, $data);
print "Wrote $bytes_written bytes\n";
close($fh);#Append writing
open(my $fh, '>>', 'log.txt') or die "Cannot open file: $!";
my $timestamp = localtime();
print $fh "[$timestamp] Log message\n";
close($fh);#File test
#Basic file test
my $file = 'test.txt';
if (-e $file) {
print "File exists\n";
}
if (-f $file) {
print "Is a regular file\n";
}
if (-d $file) {
print "Is a directory\n";
}
if (-r $file) {
print "Is readable\n";
}
if (-w $file) {
print "Is writable\n";
}
if (-x $file) {
print "Is executable\n";
}#File size and time
my $file = 'test.txt';
my $size = -s $file;
print "File size: $size bytes\n";
my $mtime = -M $file;
print "Modified $mtime days ago\n";
my $atime = -A $file;
print "Accessed $atime days ago\n";
my $ctime = -C $file;
print "Changed $ctime days ago\n";#File permissions
my $file = 'test.txt';
printf "Owner: %04o\n", (stat($file))[2] & 0777;
if (-r $file && -w $file) {
print "Readable and writable\n";
}
if (-R $file) {
print "Real user can read\n";
}
if (-W $file) {
print "Real user can write\n";
}#File Type
my $file = 'test.txt';
if (-f $file) { print "Regular file\n"; }
if (-d $file) { print "Directory\n"; }
if (-l $file) { print "Symbolic link\n"; }
if (-p $file) { print "Named pipe\n"; }
if (-S $file) { print "Socket\n"; }
if (-b $file) { print "Block special file\n"; }
if (-c $file) { print "Character special file\n"; }#File and directory operations
#Delete files
# 删除单个文件
unlink 'file.txt' or warn "Cannot delete file: $!";
# 删除多个文件
my @files = ('file1.txt', 'file2.txt', 'file3.txt');
my $count = unlink @files;
print "Deleted $count files\n";#Rename file
rename('old.txt', 'new.txt') or die "Cannot rename: $!";#Copy files
# 方法 1:使用 File::Copy
use File::Copy;
copy('source.txt', 'destination.txt') or die "Cannot copy: $!";
# 方法 2:手动复制
open(my $in, '<', 'source.txt') or die "Cannot open source: $!";
open(my $out, '>', 'destination.txt') or die "Cannot open destination: $!";
while (my $line = <$in>) {
print $out $line;
}
close($in);
close($out);#Move files
# 使用 File::Copy
use File::Copy;
move('source.txt', 'destination.txt') or die "Cannot move: $!";
# 或使用 rename
rename('source.txt', 'destination.txt') or die "Cannot move: $!";#Get file information
my $file = 'test.txt';
my @stats = stat($file);
my $dev = $stats[0]; # 设备号
my $ino = $stats[1]; # inode 号
my $mode = $stats[2]; # 文件模式
my $nlink = $stats[3]; # 硬链接数
my $uid = $stats[4]; # 用户 ID
my $gid = $stats[5]; # 组 ID
my $rdev = $stats[6]; # 特殊设备号
my $size = $stats[7]; # 文件大小
my $atime = $stats[8]; # 访问时间
my $mtime = $stats[9]; # 修改时间
my $ctime = $stats[10]; # 改变时间
my $blksize = $stats[11]; # 块大小
my $blocks = $stats[12]; # 块数量
printf "File: $file\n";
printf "Size: %d bytes\n", $size;
printf "Modified: %s\n", scalar localtime($mtime);
printf "Permissions: %04o\n", $mode & 0777;#Binary file operations
#Read binary file
open(my $fh, '<:raw', 'binary.dat') or die "Cannot open file: $!";
binmode($fh);
my $buffer;
my $bytes_read = read($fh, $buffer, 1024);
print "Read $bytes_read bytes\n";
close($fh);#Write binary file
open(my $fh, '>:raw', 'output.dat') or die "Cannot open file: $!";
binmode($fh);
my $data = pack('C*', 0x01, 0x02, 0x03, 0x04);
print $fh $data;
close($fh);#Use pack and unpack
# 写入二进制数据
open(my $fh, '>:raw', 'data.dat') or die "Cannot open file: $!";
my $header = pack('A4LL', 'TEST', 12345, 67890);
print $fh $header;
close($fh);
# 读取二进制数据
open(my $fh, '<:raw', 'data.dat') or die "Cannot open file: $!";
my $buffer;
read($fh, $buffer, 12); # 读取 12 字节
my ($magic, $num1, $num2) = unpack('A4LL', $buffer);
print "Magic: $magic\n";
print "Number 1: $num1\n";
print "Number 2: $num2\n";
close($fh);#Practical example
#Example 1: File statistics tool
#!/usr/bin/perl
use strict;
use warnings;
sub count_file_stats {
my ($filename) = @_;
open(my $fh, '<', $filename) or die "Cannot open $filename: $!";
my $line_count = 0;
my $word_count = 0;
my $char_count = 0;
while (my $line = <$fh>) {
$line_count++;
$char_count += length($line);
my @words = split /\s+/, $line;
$word_count += scalar @words;
}
close($fh);
return {
lines => $line_count,
words => $word_count,
chars => $char_count
};
}
print "请输入文件名: ";
chomp(my $filename = <STDIN>);
if (-e $filename) {
my $stats = count_file_stats($filename);
print "=== 文件统计 ===\n";
print "文件名: $filename\n";
print "行数: $stats->{lines}\n";
print "单词数: $stats->{words}\n";
print "字符数: $stats->{chars}\n";
} else {
print "文件不存在\n";
}#Example 2: Log file analyzer
#!/usr/bin/perl
use strict;
use warnings;
sub parse_log_line {
my ($line) = @_;
if ($line =~ /\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(\w+)\] (.*)/) {
return {
timestamp => $1,
level => $2,
message => $3
};
}
return undef;
}
sub analyze_log {
my ($filename) = @_;
open(my $fh, '<', $filename) or die "Cannot open $filename: $!";
my %level_counts;
my @errors;
while (my $line = <$fh>) {
my $entry = parse_log_line($line);
if ($entry) {
$level_counts{$entry->{level}}++;
if ($entry->{level} eq 'ERROR') {
push @errors, $entry;
}
}
}
close($fh);
return {
level_counts => \%level_counts,
errors => \@errors
};
}
my $log_file = 'app.log';
if (-e $log_file) {
my $analysis = analyze_log($log_file);
print "=== 日志分析 ===\n";
print "日志级别统计:\n";
foreach my $level (sort keys %{$analysis->{level_counts}}) {
printf " %s: %d\n", $level, $analysis->{level_counts}{$level};
}
print "\n错误日志:\n";
foreach my $error (@{$analysis->{errors}}) {
printf " [%s] %s\n", $error->{timestamp}, $error->{message};
}
} else {
print "日志文件不存在\n";
}#Example 3: CSV file processing
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });
# 读取 CSV
open(my $fh, '<', 'data.csv') or die "Cannot open file: $!";
my @headers = @{$csv->getline($fh)};
my @rows;
while (my $row = $csv->getline($fh)) {
my %data;
@data{@headers} = @$row;
push @rows, \%data;
}
close($fh);
# 显示数据
print "=== CSV 数据 ===\n";
foreach my $row (@rows) {
print "-" x 40 . "\n";
foreach my $header (@headers) {
printf "%-15s: %s\n", $header, $row->{$header};
}
}
# 写入 CSV
open(my $out, '>', 'output.csv') or die "Cannot create file: $!";
$csv->print($out, \@headers);
foreach my $row (@rows) {
my @values = map { $row->{$_} } @headers;
$csv->print($out, \@values);
}
close($out);#Summary
In this chapter, we learned about Perl’s file operations:
- ✅ Open and close files
- ✅ Read files (line by line, whole, binary)
- ✅Write files
- ✅ File test
- ✅ File and directory operations
- ✅ Binary file operations
Next, we'll learn about Perl Directory Operations.