【问题标题】:How to pass and read a File handle to a Perl subroutine?如何将文件句柄传递和读取到 Perl 子例程?
【发布时间】:2012-06-19 17:44:44
【问题描述】:

我想要一个从特殊文件句柄<STDIN> 中读取的 Perl 模块,并将其传递给子例程。当您看到我的代码时,您就会明白我的意思。 这是以前的样子:

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

use lib '/usr/local/custom_pm'
package Read_FH

sub read_file {
my ($filein) = @_;
open FILEIN, $filein or die "could not open $filein for read\n";
# reads each line of the file text one by one
while(<FILEIN>){
# do something
}
close FILEIN;

现在子程序将文件名(存储在$filein)作为参数,使用文件句柄打开文件,并使用细句柄逐行读取文件的每一行。

相反,我想从&lt;STDIN&gt; 获取文件名,将其存储在变量中,然后将此变量作为参数传递给子例程。 从主程序:

$file = <STDIN>;
$variable = read_file($file);

该模块的子程序如下:

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

use lib '/usr/local/custom_pm'
package Read_FH

# subroutine that parses the file
sub read_file {
my ($file)= @_;
# !!! Should I open $file here with a file handle? !!!!

# read each line of the file
while($file){
# do something
}

有人知道我该怎么做吗?我很感激任何建议。

【问题讨论】:

  • 我理解正确,您是否需要一个 CPAN 模块,或者您需要帮助更改您的模块以从 &lt;STDIN&gt; 获取文件名?
  • 我需要帮助更改我的模块以从&lt;STDIN&gt;获取文件名
  • 你有没有试过把这两行代码放到你的模块中?
  • 我做了,但我不知道如何测试它以查看它是否有效,甚至不知道如何编译它以查看其语法是否正确。
  • 请使用open的三参数形式。使用两个参数的形式,如果 '' + chomp() 给你留下像 rm -rf / | 这样的文件名,你可能会不高兴。

标签: perl subroutine filehandle


【解决方案1】:

一般来说,使用词法文件处理程序是个好主意。那是一个包含文件处理程序而不是裸词的词法变量。

您可以像传递任何其他变量一样传递它。如果您使用 read_fileFile::Slurp 中的 read_file,则不需要单独的文件处理程序,它会将内容放入变量中。

尽快关闭打开的文件句柄也是一种很好的做法,如果您真的只需要获取完整的文件内容,这应该是首选方式。

使用 File::Slurp:

use strict;
use warnings;
use autodie;
use File::Slurp;

sub my_slurp {
    my ($fname) = @_;
    my $content = read_file($fname);

    print $content; # or do something else with $content

    return 1;
}

my $filename = <STDIN>;
my_slurp($filename);

exit 0;

没有额外的模块:

use strict;
use warnings;
use autodie;

sub my_handle {
    my ($handle) = @_;
    my $content = '';

    ## slurp mode
    {
        local $/;
        $content = <$handle>
    }

    ## or line wise
    #while (my $line = <$handle>){
    #    $content .= $line;
    #}

    print $content; # or do something else with $content

    return 1;
}

my $filename = <STDIN>;
open my $fh, '<', $filename;
my_handle($fh); # pass the handle around
close $fh;

exit 0;

【讨论】:

  • 很好地解释了词法文件句柄。我同意File::Slup 可能比他自己的代码更好。
  • 感谢穆根。我想我必须学习如何使用词法文件句柄和File::Slurp 模块。
【解决方案2】:

我同意@mugen kenichi 的观点,他的解决方案比构建自己的解决方案更好。使用社区测试过的东西通常是个好主意。无论如何,您可以对自己的程序进行以下更改,以使其按照您的意愿行事。

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

package Read_FH;

sub read_file {
    my $filein = <STDIN>;
    chomp $filein; # Remove the newline at the end
    open my $fh, '<', $filein or die "could not open $filein for read\n";
    # reads each line of the file text one by one
    my $content = '';
    while (<$fh>) {
        # do something
        $content .= $_;
    }
    close $fh;

    return $content;
}

# This part only for illustration
package main;

print Read_FH::read_file();

如果我运行它,它看起来像这样:

simbabque@geektour:~/scratch$ cat test
this is a
testfile

with blank lines.
simbabque@geektour:~/scratch$ perl test.pl
test
this is a
testfile

with blank lines.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 2012-08-14
    相关资源
    最近更新 更多