无法在Perl中打开文本文件

时间:2013-01-16 07:14:17

标签: perl file-io

我从另一台服务器获取一些日志文件(格式为txt)并尝试使用我的Perl脚本解析它们。正在正确获取日志,之后我为日志目录设置了777的权限。

在此之后,我尝试通过我的Perl脚本逐个打开日志文件进行解析。现在,奇怪的事情和发生的问题,我的脚本有时能够打开文件,有时不能。简而言之,它无法打开日志文件进行解析。

此外,我已经破解了这个perl脚本,并且当它通过cron而不是手动运行时,文件打开失败的可能性更大,尽管它们在之前的两种情况下都已成功运行。我不明白问题所在。

以下是我用来打开文件的代码,

$inputDir = "/path/to/dir";
@inputFiles = <$inputDir/*>;

# inputFiles array is list of files in the log directory
foreach my $logFile(@inputFiles)
{
    # just to ensure file name is text
    $logFile = $logFile."";

    # process file only if filename contains "NOK"
    if(index($logFile,"NOK") > -1)
    {
        # opens the file
        open($ifile, '<', $logFile) or die "Error: Unable to open file for processing.";

        # file parsing takes place
    }
}

close($ifile);

我想重新尝试此代码已成功运行,并且我没有更改它的任何部分。但是,它不会每次都运行,因为它无法有时打开日志文件。有什么想法吗?

3 个答案:

答案 0 :(得分:5)

您应该在$!字符串中包含错误消息$logFile和文件名die,以查看为什么打开失败,以及哪个文件。

open($ifile, '<', $logFile) or die "Error: Unable to open $logFile: $!";

此外,这一行:

$logFile = $logFile."";

......非常多余。如果需要转换,perl将处理它。

答案 1 :(得分:0)

就像一个例子,这就是你的代码应该是什么样子。您可以尝试使用此版本

use strict;
use warnings;

my $inputDir = '/path/to/dir';
my @inputFiles = <$inputDir/*>;

foreach my $logFile (grep /NOK/, @inputFiles) {
  open my $ifile, '<', $logFile or die qq(Unable to open "$logFile": $!);
  # Process data from <$ifile>;
}

答案 2 :(得分:-1)

打开某些文件可能会失败,因为您的程序打开的文件太多了。您的程序在$inputDir中打开所有文件并在循环中处理它们。之后它会关闭最后打开的文件。

编辑:在阅读了TLP的评论并阅读perldoc -f closeperldoc -f open后,我发现TLP是正确的,$ifile中的文件句柄已关闭随后的open($ifile,'<',$logFile)。但是,如果主题创建者未显示的文件解析代码创建了对$ifile的另一个引用,则文件句柄将保持打开状态。

close的呼叫转移到if区块可以解决您的问题:

$inputDir = "/path/to/dir";
@inputFiles = <$inputDir/*>;

# inputFiles array is list of files in the log directory
foreach my $logFile(@inputFiles)
{

    # process file only if filename contains "NOK"
    if(index($logFile,"NOK") > -1)
    {
        # opens the file
        # added my to $ifile to keep local to this scope
        open(my $ifile, '<', $logFile) or die "Error: Unable to open file for processing.";

        # file parsing takes place

        # close current file
        close($ifile);
    }
}