【问题标题】:Perl File pointersPerl 文件指针
【发布时间】:2014-01-21 15:22:58
【问题描述】:

我对这两个文件有疑问: 1)

use strict;
use warnings;
use v5.12;
use externalModule;

my $file = "test.txt";

unless(unlink $file){ # unlink is UNIX equivalent of rm

    say "DEBUG: No test.txt persent";

}

unless (open FILE, '>>'.$file) {
    die("Unable to create $file");
 }

say FILE "This name is $file"; # print newline automatically

unless(externalModule::external_function($file)) {
    say "error with external_function";
}

print FILE "end of file\n";

close FILE; 

和外部模块(.pm)

use strict;
use warnings;
use v5.12;

package externalModule;

sub external_function {

    my $file = $_[0]; # first arguement

    say "externalModule line 11: $file";

    # create a new file handler
    unless (open FILE, '>>'.$file) {
        die("Unable to create $file");
    }

    say FILE "this comes from an external module";

    close FILE;

    1;

}

1; # return true

现在, 在第一个 perl 脚本第 14 行:

# create a new file handler
unless (open FILE, '>>'.$file) {
    die("Unable to create $file");
}

如果有的话

'>'.$file 

相反,外部模块打印的字符串不会显示在最终的 test.txt 文件中。

为什么会这样??

亲切的问候

【问题讨论】:

  • perldoc perlopentut
  • 注意:它是一个文件 handle(保存的东西),而不是文件 handler(处理的东西)

标签: perl perl-module


【解决方案1】:

'>' 表示打开文件进行输出,可能会覆盖它(“破坏”)。 >> 表示如果它已经存在则附加到它。

顺便说一句,建议使用open的3个参数形式和词法文件句柄:

open my $FH, '>', $file or die "Cannot open $file: $!\n";

【讨论】:

  • 感谢 3 参数函数。我现在可以将文件处理程序作为参数传递,并且脚本适用于“>”版本。我会给你打勾,但它没有回答我为什么它被覆盖的问题。 :( 非常感谢!
【解决方案2】:

如果您在主函数中使用>$file,它将写入文件的开头,并缓冲输出。因此,在您的外部函数返回后,“文件结尾”将附加到缓冲区,并刷新缓冲区——文件指针仍位于文件中的位置 0,因此您只需覆盖来自外部函数的文本.在外部函数中尝试更长的文本,你会发现它的最后一部分仍然存在,而第一部分被覆盖了。

【讨论】:

    【解决方案3】:

    这是非常古老的语法,在现代 Perl 中不推荐使用。大约 10 年前“仅”在 5.6.1 中引入的 3 参数版本是首选。使用词法变量作为文件句柄也是如此,而不是大写的裸字。

    无论如何,>> 表示为 append 打开,而> 表示为 write 打开,这将删除文件中的所有现有数据。

    【讨论】:

      【解决方案4】:

      当您再次重新打开文件时,您正在破坏文件。 > 表示打开文件进行写入,如果旧文件存在则删除并创建一个新文件。 >> 表示打开文件进行写入,如果文件已经存在则追加数据。

      如您所见,在模块和程序之间来回传递FILE 非常困难。

      最新的语法是对文件句柄使用词法范围的变量:

      use autodie;
      
      # Here I'm using the newer three parameter version of the open statement.
      # I'm also using '$fh' instead of 'FILE' to store the pointer to the open
      # file. This makes it easier to pass the file handle to various functions.
      #
      # I'm also using "autodie". This causes my program to die due to certain
      # errors, so if I forget to test, I don't cause problems. I can use `eval`
      # to test for an error if I don't want to die.
      
      open my $fh, ">>", $file;  # No die if it doesn't open thx to autodie
      
      # Now, I can pass the file handle to whatever my external module needs
      # to do with my file. I no longer have to pass the file name and have
      # my external module reopen the file
      
      externalModule::xternal_function( $fh );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-28
        • 1970-01-01
        • 2021-11-06
        • 1970-01-01
        • 1970-01-01
        • 2010-10-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多