【问题标题】:Error with opening a filehandle打开文件句柄时出错
【发布时间】:2012-03-05 03:30:37
【问题描述】:

我刚刚开始使用 Perl,我只是入门级,我在打开文件句柄时遇到了麻烦。

代码如下:

#!/usr/bin/perl -w

$proteinfilename = 'peptide';

open(PROTEINFILE, $proteinfilename) or die "Can't write to file '$proteinfilename' [$!]\n";

$protein = <PROTEINFILE>;

close PROTEINFILE;

print $protein;

exit;

每次我尝试运行程序时,它都会给我一个错误

readline() on closed filehandle PROTEINFILE at C:\BIN\protein.pl

或

Can't write to file 'peptide' [No such file or directory]

你能帮我解决这个问题吗?我将 peptide 文件保存为 .txt,并将其与 protein.pl 放在同一文件夹中。我还能做些什么来完成这项工作?

【问题讨论】:

  • 文件是“peptide”还是“peptide.txt”?你是如何运行脚本的?运行时,脚本的位置不是您的工作目录所必需的。

标签: perl filehandle


【解决方案1】:

您告诉perl 在当前目录中打开文件peptide,但它在那里找不到这样的文件(“没有这样的文件或目录”)。

也许当前目录不是C:\BIN,而是您声明文件所在的目录。您可以通过移动文件、使用绝对路径或更改 当前目录是脚本所在的目录。

use Cwd        qw( realpath );
use Path::File qw( file );

chdir(file(realpath($0))->dir);

也许该文件未命名为peptide。例如,它实际上可能被命名为peptide.txt。 Windows 隐藏了它默认识别的扩展,这是我讨厌的一个功能。您可以通过重命名文件或使用正确的文件名来解决此问题。

【讨论】:

    【解决方案2】:

    您是要打开文件进行读取还是写入?您的open 声明打开它以供阅读;你的错误信息说“写作”。你用它来阅读——所以你的错误信息很混乱,我相信。

    如果你得到“没有这样的文件或目录”错误,这意味着不管你怎么想,“肽”这个名字并不是当前目录中的文件名。 Perl 不会为您添加文件名的扩展名;如果您的文件实际上是peptide.txt(因为您提到它是一个“txt 文件”),那么这就是您需要指定给open 的内容。如果您运行perl protein.pl 并且peptide(或peptide.txt)在当前目录中,那么不清楚您的问题是什么。如果您的脚本在C:\BIN 目录中,而您的当前目录不是C:\BIN 但peptide(或peptide.txt)也在C:\BIN 中,那么您需要安排打开C:/bin/peptide 或c:/bin/peptide.txt。注意从反斜杠到斜杠的切换。反斜杠具有特定于 Perl 作为转义字符的含义,Windows 很乐意用斜杠代替反斜杠。如果必须使用反斜杠,请在名称周围使用单引号:

    my $proteinfilename = 'C:\BIN\peptide.txt';
    

    从命令行参数中获取蛋白质文件名可能是最简单的;这使您可以灵活地将脚本放在 PATH 上的任何位置,并将文件放在您选择的任何位置。


    帮助您的 Perl 的两条建议:

    1. 使用open 的三元形式和词法文件句柄,如:

      open my $PROTEINFILE, '<', $proteinfilename or
          die "Can't open file '$proteinfilename' for reading [$!]\n";
      
      my $protein = <$PROTEINFILE>;
      
      close $PROTEINFILE;
      

      请注意,这会从文件中读取一行。如果您需要将整个文件 slurp 到 $protein,那么您必须做更多的工作。有一些模块可以为您处理啜饮,但您也可以简单地使用:

      my $protein;
      { local $/; $protein = <$PROTEINFILE>; }
      

      这会将行分隔符设置为undef,这意味着整个文件在一次读取操作中被slurped。 $/ 变量是全局变量,但这会在最小范围内调整其值。请注意,$protein 是在包含 slurp 操作的块之外声明的!

    2. 使用use strict; 以及-w 或use warnings;。随着时间的流逝,它会为您节省悲伤。

    我使用 Perl 才 20 年;如果没有use strict; 和use warnings;,我不会写一个严肃的脚本,因为我不相信我发现愚蠢错误的能力(Perl 会为我做这件事)。我不会犯那么多错误,但是 Perl 在很多情况下救了我,因为我使用了它们。

    【讨论】:

    • 我不太喜欢看到人们自动推荐 autovivved 句柄,而这不是提问者的问题所在。它分散了他们修复真正错误的注意力,无论它是什么。如果你要使用三个参数,编码在哪里?
    • 感谢您的帮助,我在命名 $proteinfilename 时在肽文件中添加了 C:\user\BIN 扩展名,并且成功了!
    【解决方案3】:

    您的程序将如何进行

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    my $proteinfilename = 'peptide.txt';
    
    open(PROTEINFILE, $proteinfilename) or die "Can't write to file '$proteinfilename' [$!]\n";
    
    my $protein = <PROTEINFILE>;
    
    close PROTEINFILE;
    
    print $protein;
    

    您需要在末尾添加文件扩展名(例如 .txt),如下所示。

    my $proteinfilename = 'peptide.txt';
    

    你的程序说peptide_test.pl和输入文本文件peptide.txt应该在同一个目录下。
    如果它们不在同一目录中,请使用如下绝对路径。

    my $proteinfilename = 'C:\somedirectory\peptide.txt';
    

    注意:在绝对路径的情况下使用单引号。这将忽略路径中的反斜杠\。

    现在关于错误,如果你不使用die 语句,你会得到错误

    readline<> on closed filehandle PROTEINFILE at C:\BIN\protein.pl
    

    使用模具后,

    or die $! ;

    你会得到错误No such file or directory.

    也总是

    use strict;  
    use warnings;
    

    -w 在perl 5.6 之后被弃用。这两行/语句将帮助您找到拼写错误、语法错误

    还有一个,我认为你最后不需要exit;。 Refer exit function.

    【讨论】:

    • 感谢您的帮助,让程序按照您所说的那样运行
    猜你喜欢
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多