我想使用Path::Tiny
模块来阅读一些文本文件。
我创建了我想要在文件list.txt
中读取的文件名列表,但是当我运行我的代码时,我收到此错误消息
Error open <<:raw:encoding<UTF-8>> on '[thefirstfilenames.txt]': Invalid argument at Test2.PL line 15.
我的代码如下:
use strict;
use 5.010;
use warnings;
use Path::Tiny qw(path); # http://perlmaven.com/use-path-tiny-to-read-and-write-file
my $file = "list.txt";
open (FH, "< $file") or die "Can't open $file for read: $!";
my @list = <FH>;
close FH or die "Cannot close $file: $!";
my $size = @list;
for ( my $i = 0; $i < $size; $i++ ) {
my $filename = "$list[$i]";
my $content = path($filename)->slurp_utf8;
print "$content\n";
}
这有什么解决方案吗?当我手动逐个放置文件名时,它工作正常。
答案 0 :(得分:3)
我不确定您如何将Invalid argument
(EINVAL)视为错误,但是从错误消息中可以清楚地看到文件中的行包含{{{{{{ 1}}括号。这可能不是有效的文件名,您需要从文件或程序中删除它们。
Buuut ...我怀疑你没有向我们展示真正的错误信息,在寻求调试帮助时非常重要。我怀疑你得到的是这样的东西,换行和所有。
[thefirstfilenames.txt]
当您从文件中读取时,每行仍然有一个换行符。你需要删除它。这通常使用chomp
完成,可以一次完成整个列表。
还可以采取其他措施来改进代码。由于您已经在使用Path :: Tiny,请通过调用Path::Tiny->lines
替换程序的开头。并称之为:Error open <<:raw:encoding<UTF-8>> on 'somefilename.txt
': Invalid argument at Test2.PL line 15.
。
@filenames
最重要的是摆脱C风格的循环和let Perl iterate through the @filenames
。
my @filenames = path($file)->lines_utf8;
chomp @filenames;
答案 1 :(得分:1)
主要问题是您不会从list.txt
读取的文件名末尾删除不需要的字符。这意味着$filename
的每个值仍然会包含在方括号[ ... ]
中,并且附加了一个不需要的"\n"
,您应该将其删除
这是重写你自己的代码来解决这个问题。它还纠正了一些老式的技术,例如使用词法文件句柄和三参数形式的open
,并迭代内容<{em>} @list
而非其索引
use strict;
use warnings;
use Path::Tiny 'path';
my $file = 'list.txt';
my @files = do {
open my $fh, '<', $file or die qq{Unable to open "$file" for input: $!};
map { / \[ ( [^\[\]]+ ) \] /x } <$fh>;
};
for my $file ( @files) {
my $content = path($file)->slurp_utf8;
print $content, "\n";
}
这对你有用,但在我看来Path::Tiny
在这里是不必要的,slurp_utf8
在Windows行结尾中保留了CR字符,这不是标准的Perl行为,可能不是想要的。使用do
块打开文件并本地化$/
可以很容易地进行啜食。它的优势在于所有内容都是在标准Perl中完成的,任何阅读它的人都不必猜测path($file)->slurp_utf8
可能会做什么(这显然不是你所期望的直接啜泣)。喜欢这个
use strict;
use warnings;
my $file = 'list.txt';
my @files = do {
open my $fh, '<', $file or die qq{Unable to open "$file" for input: $!};
<$fh>;
};
chomp @files;
for my $file ( @files) {
my $content = do {
open my $fh, '<:encoding(utf-8)', $file or die qq{Unable to open "$file" for input: $!};
local $/;
<$fh>;
};
print $content, "\n";
}