如何将小文本文件的内容读入Perl中的标量?

时间:2023-02-06 12:14:35

I have a small text file that I'd like to read into a scalar variable exactly as it is in the file (preserving line separators and other whitespace).

我有一个小文本文件,我想读入一个标量变量,就像它在文件中一样(保留行分隔符和其他空格)。

The equivalent in Python would be something like

Python中的等价物就像是

buffer = ""

try:
    file = open("fileName", 'rU')
    try:
        buffer += file.read()
    finally:
        file.close()
except IOError:
    buffer += "The file could not be opened."

This is for simply redisplaying the contents of the file on a web page, which is why my error message is going into my file buffer.

这只是为了简单地重新显示网页上文件的内容,这就是我的错误信息进入我的文件缓冲区的原因。

8 个解决方案

#1


19  

From the Perl Cookbook:

来自Perl Cookbook:

my $filename = 'file.txt';
open( FILE, '<', $filename ) or die 'Could not open file:  ' . $!;

undef $/;
my $whole_file = <FILE>;

I would localize the changes though:

我会将这些变化本地化:

my $whole_file = '';
{
    local $/;
    $whole_file = <FILE>;
}

#2


18  

As an alternative to what Alex said, you can install the File::Slurp module (cpan -i File::Slurp from the command line) and use this:

作为Alex所说的替代方法,您可以安装File :: Slurp模块(命令行中的cpan -i File :: Slurp)并使用:

use File::Slurp;
# Read data into a variable
my $buffer = read_file("fileName");
# or read data into an array
my @buffer = read_file("fileName");

Note that this dies (well... croaks, but that's just the proper way to call die from a module) on errors, so you may need to run this in an eval block to catch any errors.

请注意,这会在错误中死掉(嗯......呱呱叫,但这只是从模块调用die的正确方法),因此您可能需要在eval块中运行它以捕获任何错误。

#3


15  

If I don't have Slurp or Perl6::Slurp near by then I normally go with....

如果我附近没有Slurp或Perl6 :: Slurp那么我通常会跟....

open my $fh, '<', 'file.txt' or die $!;

my $whole_file = do { local $/; <$fh> };

#4


1  

There is a discussion of the various ways to read a file here.

这里讨论了读取文件的各种方法。

#5


1  

I don't have enough reputation to comment, so I apologize for making this another post.

我没有足够的声誉来评论,所以我为另一篇文章道歉。

@ Harold Bamford: $/ should not be an obscure variable to a Perl programmer. A beginner may not know it, but he or she should learn it. The join method is a poor choice for the reasons stated in the article linked by hackingwords above. Here's the relevant quotation from the article:

@ Harold Bamford:$ /不应该是Perl程序员的一个模糊变量。初学者可能不知道,但他或她应该学习它。由于上面通过hackingwords链接的文章中所述的原因,连接方法是一个糟糕的选择。这是文章中的相关引文:

That needlessly splits the input file into lines (join provides a list context to ) and then joins up those lines again. The original coder of this idiom obviously never read perlvar and learned how to use $/ to allow scalar slurping.

这不必要地将输入文件拆分为行(连接提供列表上下文),然后再次连接这些行。这个成语的原始编码器显然从未读过perlvar并学会了如何使用$ /来允许标量啜饮。

#6


1  

You could do something like:

你可以这样做:

$data_file="somefile.txt";
open(DAT, $data_file);
@file_data = <DAT>;
close(DAT);

That'll give you the file contents in an array, that you can use for whatever you want, for example, if you wanted each individual line, you could do something like:

这将为您提供数组中的文件内容,您可以将其用于任何您想要的内容,例如,如果您想要每个单独的行,您可以执行以下操作:

foreach $LINE (@file_data)
{
    dosomethingwithline($LINE);
}

For a full usage example:

有关完整用法示例:

my $result;
$data_file = "somefile.txt";
my $opened = open(DAT, $data_file);
if (!$opened)
{
    $result = "Error.";
}
else
{
    @lines = <DAT>;
    foreach $LINE (@lines)
    {
        $result .= $LINE;
    }
    close(DAT);
}

Then you can use $result however you need. Note: This code is untested, but it should give you an idea.

然后你可以根据需要使用$ result。注意:此代码未经测试,但它应该给你一个想法。

#7


1  

I'd tweak draegtun's answer like this, to make it do exactly what was being asked:

我会像这样调整draegtun的答案,让它完全按照要求做的:

my $buffer;
if ( open my $fh, '<', 'fileName' ) {
    $buffer = do { local $/; <$fh> };
    close $fh;
} else {
    $buffer = 'The file could not be opened.';
}

#8


0  

Just join all lines together into a string:

只需将所有行连接成一个字符串:

open(F, $file) or die $!;
my $content = join("", <F>); 
close F;

(It was previously suggested to use join "\n" but that will add extra newlines. Each line already has a newline at its end when it's read.)

(之前建议使用连接“\ n”,但这会添加额外的换行符。每行读取时都有一个换行符。)

#1


19  

From the Perl Cookbook:

来自Perl Cookbook:

my $filename = 'file.txt';
open( FILE, '<', $filename ) or die 'Could not open file:  ' . $!;

undef $/;
my $whole_file = <FILE>;

I would localize the changes though:

我会将这些变化本地化:

my $whole_file = '';
{
    local $/;
    $whole_file = <FILE>;
}

#2


18  

As an alternative to what Alex said, you can install the File::Slurp module (cpan -i File::Slurp from the command line) and use this:

作为Alex所说的替代方法,您可以安装File :: Slurp模块(命令行中的cpan -i File :: Slurp)并使用:

use File::Slurp;
# Read data into a variable
my $buffer = read_file("fileName");
# or read data into an array
my @buffer = read_file("fileName");

Note that this dies (well... croaks, but that's just the proper way to call die from a module) on errors, so you may need to run this in an eval block to catch any errors.

请注意,这会在错误中死掉(嗯......呱呱叫,但这只是从模块调用die的正确方法),因此您可能需要在eval块中运行它以捕获任何错误。

#3


15  

If I don't have Slurp or Perl6::Slurp near by then I normally go with....

如果我附近没有Slurp或Perl6 :: Slurp那么我通常会跟....

open my $fh, '<', 'file.txt' or die $!;

my $whole_file = do { local $/; <$fh> };

#4


1  

There is a discussion of the various ways to read a file here.

这里讨论了读取文件的各种方法。

#5


1  

I don't have enough reputation to comment, so I apologize for making this another post.

我没有足够的声誉来评论,所以我为另一篇文章道歉。

@ Harold Bamford: $/ should not be an obscure variable to a Perl programmer. A beginner may not know it, but he or she should learn it. The join method is a poor choice for the reasons stated in the article linked by hackingwords above. Here's the relevant quotation from the article:

@ Harold Bamford:$ /不应该是Perl程序员的一个模糊变量。初学者可能不知道,但他或她应该学习它。由于上面通过hackingwords链接的文章中所述的原因,连接方法是一个糟糕的选择。这是文章中的相关引文:

That needlessly splits the input file into lines (join provides a list context to ) and then joins up those lines again. The original coder of this idiom obviously never read perlvar and learned how to use $/ to allow scalar slurping.

这不必要地将输入文件拆分为行(连接提供列表上下文),然后再次连接这些行。这个成语的原始编码器显然从未读过perlvar并学会了如何使用$ /来允许标量啜饮。

#6


1  

You could do something like:

你可以这样做:

$data_file="somefile.txt";
open(DAT, $data_file);
@file_data = <DAT>;
close(DAT);

That'll give you the file contents in an array, that you can use for whatever you want, for example, if you wanted each individual line, you could do something like:

这将为您提供数组中的文件内容,您可以将其用于任何您想要的内容,例如,如果您想要每个单独的行,您可以执行以下操作:

foreach $LINE (@file_data)
{
    dosomethingwithline($LINE);
}

For a full usage example:

有关完整用法示例:

my $result;
$data_file = "somefile.txt";
my $opened = open(DAT, $data_file);
if (!$opened)
{
    $result = "Error.";
}
else
{
    @lines = <DAT>;
    foreach $LINE (@lines)
    {
        $result .= $LINE;
    }
    close(DAT);
}

Then you can use $result however you need. Note: This code is untested, but it should give you an idea.

然后你可以根据需要使用$ result。注意:此代码未经测试,但它应该给你一个想法。

#7


1  

I'd tweak draegtun's answer like this, to make it do exactly what was being asked:

我会像这样调整draegtun的答案,让它完全按照要求做的:

my $buffer;
if ( open my $fh, '<', 'fileName' ) {
    $buffer = do { local $/; <$fh> };
    close $fh;
} else {
    $buffer = 'The file could not be opened.';
}

#8


0  

Just join all lines together into a string:

只需将所有行连接成一个字符串:

open(F, $file) or die $!;
my $content = join("", <F>); 
close F;

(It was previously suggested to use join "\n" but that will add extra newlines. Each line already has a newline at its end when it's read.)

(之前建议使用连接“\ n”,但这会添加额外的换行符。每行读取时都有一个换行符。)