You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl多文件解析代码修正请求:文件打开失败报错排查

问题分析与修正方案

你遇到的Cannot open file, No such file or directory错误,核心原因是**readdir返回的仅是文件名,而非完整路径**——当你直接用open(my $fh, $file)时,Perl会在当前工作目录寻找这个文件,而不是你遍历的NotProcessed目录下。另外代码里还有几处小问题需要一并修正:

关键错误点

  • 缺少文件路径拼接:必须把遍历的目录$dir和文件名$file组合成完整路径"$dir/$file"才能正确打开文件
  • 关闭文件的对象错误:close $file应该改为close $fh(关闭的是文件句柄,不是文件名)
  • 数组初始化不当:@fileList = ""会把数组初始化为包含一个空字符串的元素,应该改为@fileList = ()
  • 冗余的判断:已经有next if $file =~ /^\.\.?$/;,后面的next if $file eq "." or $file eq "..";是重复的,可以删除

修正后的完整代码

use strict;
use warnings; # 建议加上这个,能帮你捕获更多潜在问题

my $dir = $ARGV[0];
my $dp_dpd = $ENV{'DP_DPD'};
my $log_dir = $ENV{'DP_LOG'};
my $xmlFlag = 0;
my @fileList = (); # 正确初始化空数组
my @not_proc_dir = `find $dp_dpd -type d -name "NotProcessed"`;

foreach my $dir (@not_proc_dir) {
    chomp ($dir);
    opendir (DIR, $dir) or die "Couldn't open directory, $!";
    while ( my $file = readdir DIR) {
        next if $file =~ /^\.\.?$/; # 跳过.和..,无需重复判断
        next if (-d "$dir/$file"); # 这里也要拼接路径,否则判断的是当前目录下的子目录
        if ($file =~ /.xml$/ig) {
            $xmlFlag = 1;
            my $full_path = "$dir/$file"; # 拼接完整路径
            print "$full_path\n";
            open(my $fh, '<', $full_path) or die "Cannot open file $full_path, $!"; # 加上打开模式<更清晰
            @fileList = <$fh>;
            close $fh; # 关闭文件句柄而非文件名
        }
    }
    closedir DIR;
}

额外优化建议

  • 加上use warnings;:这是Perl脚本的最佳实践,能帮你发现很多容易忽略的问题
  • 打开文件时显式指定模式:open(my $fh, '<', $full_path)比省略模式更清晰,也更安全
  • 避免使用反引号执行find:可以用Perl内置的File::Find模块来遍历目录,更符合Perl风格,也避免了shell命令的潜在风险,示例如下:
use strict;
use warnings;
use File::Find;

my $dp_dpd = $ENV{'DP_DPD'};
my $xmlFlag = 0;
my @fileList = ();

find(sub {
    return unless -f $_; # 只处理文件
    return unless /\.xml$/i; # 匹配XML文件
    $xmlFlag = 1;
    my $full_path = $File::Find::name;
    print "$full_path\n";
    open(my $fh, '<', $full_path) or die "Cannot open file $full_path, $!";
    @fileList = <$fh>;
    close $fh;
}, $dp_dpd);

这个版本用File::Find替代了shell的find命令,不需要自己处理目录遍历的细节,代码更简洁可靠。

内容的提问来源于stack exchange,提问作者kaye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:32:48