🎬 HoRain云小助手个人主页

 🔥 个人专栏: 《Linux 系列教程》《c语言教程

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

专栏介绍

专栏名称

专栏介绍

《C语言》

本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。

《网络协议》

本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制!

《docker容器精解篇》

全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。

《linux系列》

本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。

《python 系列》

本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。

《试题库》

本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等)

目录

⛳️ 推荐

专栏介绍

Perl 文件操作

一、打开文件

基本语法

带编码的打开

二、读取文件内容

1. 逐行读取(推荐)

2. 一次性读取整个文件

3. 读取为数组

4. 读取前 N 行

三、写入文件内容

1. 简单写入

2. 写入多个字符串

3. 使用 here-doc

四、常用文件操作模式对比

五、文件测试运算符

实用示例

六、文件操作实用场景

场景1:复制文件

场景2:删除空文件

场景3:文件备份

场景4:查找特定内容

场景5:替换文件内容

七、目录与路径操作

1. 遍历目录

2. 创建目录

3. 获取文件基本信息

4. 跨平台路径构建

八、文件锁定

九、常用第三方模块

Path::Tiny 示例

File::Copy 示例

十、完整实用示例

十一、最佳实践建议


img

Perl 文件操作

Perl 的文件操作功能非常强大,从简单的文本读写到复杂的二进制处理都有完善的 API。以下是完整指南:


一、打开文件

基本语法

open my $fh, '<', $filename;        # 只读
open my $fh, '>', $filename;        # 只写(覆盖)
open my $fh, '>>', $filename;       # 追加
open my $fh, '+<', $filename;       # 读写
open my $fh, '+>', $filename;       # 读写并覆盖

**最佳实践:**使用三参数形式,更明确安全

#!/usr/bin/perl
use strict;
use warnings;

# 推荐方式
my $file = "data.txt";
if (open my $fh, '<', $file) {
    print "文件已打开\n";
    close $fh;
} else {
    die "无法打开文件: $!";  # $! 包含错误信息
}

带编码的打开

use Encode qw(decode encode);

open(my $fh, '<:encoding(UTF-8)', 'utf8_file.txt');
open(my $fh, '>:encoding(UTF-8)', 'output_utf8.txt');

二、读取文件内容

1. 逐行读取(推荐)

open my $fh, '<', 'data.txt' or die "无法打开: $!";
while (my $line = <$fh>) {
    chomp $line;              # 去除末尾换行符
    print "$line\n";
}
close $fh;

2. 一次性读取整个文件

# 方式1:输入模式设置
local $/;           # 清空记录分隔符
open my $fh, '<', 'data.txt' or die $!;
my $content = <$fh>; # 读取全部
close $fh;

# 方式2:使用 slurp 模块
use File::Slurp;
my $content = read_file('data.txt');

3. 读取为数组

open my $fh, '<', 'data.txt' or die $!;
my @lines = <$fh>;   # 所有行作为列表
close $fh;

print join("\n", @lines);

4. 读取前 N 行

open my $fh, '<', 'data.txt' or die $!;
for (0..9) {          # 读取前 10 行
    last unless defined($_ = <$fh>);
    chomp;
    print "$_\n";
}
close $fh;

三、写入文件内容

1. 简单写入

open my $fh, '>', 'output.txt' or die $!;
print $fh "第一行\n";
print $fh "第二行\n";
print $fh "第三行\n";
close $fh;

2. 写入多个字符串

open my $fh, '>', 'output.txt' or die $!;
print $fh @text_lines;    # @text_lines是预定义的数组
close $fh;

3. 使用 here-doc

open my $fh, '>', 'script.sh' or die $!;
print $fh <<'END_SCRIPT';
#!/bin/bash
echo "Hello"
exit 0
END_SCRIPT
close $fh;

四、常用文件操作模式对比

模式 说明 目标
< 只读 打开失败时创建新文件会报错
> 只写(截断) 如果文件存在则清空,否则创建
>> 追加 在文件末尾追加
+< 读写 保留现有内容
+> 读写 先清空再读写

五、文件测试运算符

Perl 提供大量内置函数用于文件属性检测:

my $file = "example.txt";

# 基础状态测试
-e $file        # 文件是否存在
-f $file        # 是否为普通文件
-d $file        # 是否为目录
-r $file        # 是否可读
-w $file        # 是否可写
-x $file        # 是否可执行
-O $file        # 是否属当前用户
-T $file        # 是否为文本文件
-B $file        # 是否为二进制文件

# 时间与修改时间
-M $file        # 修改时间(自启动以来的小时数)
-A $file        # 访问时间
-C $file        # 更改时间(inode时间戳)

# 其他
-z $file        # 文件大小为0
-t $filehandle  # 是否是终端
-s $file        # 文件大小(字节数)
-S $file        # 是否为套接字
-L $file        # 是否为符号链接
-p $file        # 是否为管道/FIFO
-G $file        # 是否属于组所有者

实用示例

my $file = "test.txt";

if (-e $file && -f $file) {
    if (-r $file && -w $file) {
        print "文件可读写\n";
    }
    if (-s $file > 1024) {
        print "文件大小超过 1KB\n";
    }
}

六、文件操作实用场景

场景1:复制文件

sub copy_file {
    my ($src, $dst) = @_;
    
    open my $in, '<', $src or die "无法读取 $src: $!";
    open my $out, '>', $dst or die "无法写入 $dst: $!";
    
    while (my $line = <$in>) {
        print $out $line;
    }
    
    close $in;
    close $out;
    
    print "复制完成\n";
}

场景2:删除空文件

sub delete_empty_files {
    my (@files) = @_;
    foreach my $file (@files) {
        next unless -f $file;      # 检查是否是文件
        next if -s $file > 0;      # 非空文件跳过
        unlink $file;              # 删除文件
        print "已删除空文件: $file\n";
    }
}

场景3:文件备份

sub backup_file {
    my ($original) = @_;
    my ($timestamp) = time;
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($timestamp);
    my $backup_name = "$original." . sprintf("%d%02d%02d%02d%02d", 
                                              $year+1900, $mon+1, $mday, 
                                              $hour, $min);
    
    copy_file($original, $backup_name);
    return $backup_name;
}

场景4:查找特定内容

sub grep_file {
    my ($file, $pattern) = @_;
    my @matches;
    
    open my $fh, '<', $file or die $!;
    while (my $line = <$fh>) {
        push @matches, $line if $line =~ /$pattern/;
    }
    close $fh;
    
    return @matches;
}

my @results = grep_file('data.txt', '/error/i');
foreach my $match (@results) {
    print $match;
}

场景5:替换文件内容

sub replace_in_file {
    my ($file, $search, $replace) = @_;
    
    system("cp $file ${file}.bak") || die "备份失败";  # 先备份
    
    open my $in, '<', $file or die $!;
    open my $tmp, '>', "${file}.tmp" or die $!;
    
    while (my $line = <$in>) {
        $line =~ s/$search/$replace/g;
        print $tmp $line;
    }
    
    close $in;
    close $tmp;
    
    rename "${file}.tmp", $file or die "重命名失败";
    warn "替换完成";
}

七、目录与路径操作

1. 遍历目录

opendir my $dir, '.' or die "无法打开目录: $!";
my @entries = readdir $dir;
closedir $dir;

foreach my $entry (@entries) {
    next if $entry eq '.' || $entry eq '..';
    print "$entry\n";
}

2. 创建目录

mkdir 'new_dir', 0755 or die "创建失败: $!" unless -d 'new_dir';

3. 获取文件基本信息

use File::stat;
my $st = stat('/etc/passwd');

print "名称:", basename($st->name), "\n";
print "大小:", $st->size, "\n";
print "权限:", oct((substr(sprintf('%o', $st->mode), -4))) , "\n";

4. 跨平台路径构建

use File::Spec;

my $full_path = File::Spec->catfile('home', 'user', 'docs', 'file.txt');
# Windows: home\user\docs\file.txt
# Unix: home/user/docs/file.txt

my ($vols, $dirs, $file) = File::Spec->splitpath('/path/to/file.txt');
my $reconstructed = File::Spec->catpath($vols, $dirs, $file);

八、文件锁定

use Fcntl qw(:DEFAULT :flock);

open my $fh, '>>', 'lock_test.txt' or die $!;
if (flock($fh, LOCK_EX)) {         # 排他锁
    print $fh "写入数据\n";
    flock($fh, LOCK_UN);           # 释放锁
} else {
    die "无法获取锁\n";
}
close $fh;

九、常用第三方模块

模块 用途
File::Find 递归遍历目录树
Path::Tiny 现代路径处理
IO::File 面向对象文件操作
File::Copy 复制/移动文件
Archive::Zip 压缩包操作
Encode 字符编码处理

Path::Tiny 示例

use Path::Tiny;

my $file = path('data.txt');
$file->slurp;           # 读取全部内容
$file->spew(@lines);    # 写入多行
$file->child('sub')->exists;  # 检查子文件

File::Copy 示例

use File::Copy;

copy('src.txt', 'dst.txt') or die "复制失败: $!";
move('old.txt', 'new.txt') or die "移动失败: $!";
rename('temp.txt', 'final.txt');

十、完整实用示例

#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use IO::Handle;

# 日志文件写入(带自动创建目录)
sub log_message {
    my ($level, $message) = @_;
    my $log_dir = dirname($ARGV[0]);
    mkdir $log_dir unless -d $log_dir;
    
    my $log_file = "$log_dir/app.log";
    open my $fh, '>>', $log_file or die "无法写日志: $!";
    
    local $fh->autoflush(1);  # 立即输出
    printf $fh "[%s] %s: %s\n", scalar(localtime), $level, $message;
    close $fh;
}

# 按行处理大文件
sub process_large_file {
    my ($input, $output) = @_;
    
    open my $in, '<:encoding(UTF-8)', $input or die $!;
    open my $out, '>:encoding(UTF-8)', $output or die $!;
    
    while (my $line = <$in>) {
        # 在这里处理每行数据
        print $out $line if $line !~ /^#/;  # 跳过注释行
    }
    
    close $in;
    close $out;
}

# 统计文件行数
sub count_lines {
    my ($file) = @_;
    open my $fh, '<', $file or die $!;
    my $count = () = <$fh>;  # 强制列表上下文计数
    close $fh;
    return $count;
}

# 主程序测试
if (__FILE__ ne $INC{'main.pl'}) {
    log_message('INFO', '程序启动');
    process_large_file('input.txt', 'output.txt');
    my $lines = count_lines('output.txt');
    print "处理完成,共 $lines 行\n";
}

十一、最佳实践建议

原则 说明
始终关闭文件句柄 使用 close()eval 包裹确保关闭
使用三参数 open open FILEHANDLE, MODE, FILENAME
错误处理 使用 or die 或条件判断检查返回值
编码声明 读写不同编码时使用 :encoding
及时释放资源 do {} 块或对象管理生命周期
先备份再修改 对重要文件先做 .bak 备份
避免硬编码路径 使用 File::Spec 兼容多平台

掌握这些文件操作技巧,你就可以从容应对各种文件处理任务!

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐