我正在编写一个只读取文件的脚本。我遇到的一个问题是,如果我传入路径(使用Getoptions :: Long),它会告诉我文件或目录不存在,即使它可以打印我的文件名。例如:
thomaswtsang @ alfred:perl $ perl~ / Dropbox / dev / test-monkey / perl / fileReader.pl --path~ / Dropbox / dev / test-monkey / diff 没有这样的文件或目录:f1.txt at /Users/thomaswtsang/Dropbox/dev/test-monkey/perl/fileReader.pl第67行。
然后......转到该目录......
thomaswtsang @ alfred:diff $ perl~ / Dropbox / dev / test-monkey / perl / fileReader.pl --path~ / Dropbox / dev / test-monkey / diff (1/3)阅读f1.txt ...
(2/3)阅读f2.txt ...
阅读21 B
完整!
我真的不明白为什么我会这样做。权限问题?
my $path = shift; my $run_in_fg = shift; if (length($path) == 0){ if ($run_in_fg){print "Using current directory...\n";} $path = cwd(); } print $path . "\n"; opendir my $dir, $path or die "Cannot open directory: $!"; my @files = readdir $dir; my $num_files = $#files; my $i = 1; my $total_size = 0; $SIG{'INT'} = sub {print "\n";print_read_size($total_size); exit 1;}; foreach my $file (@files){ if ($file =~ m/^\.+$/){next;} $file =~ s/[\r\n]+$//; open FILE, "<", $file or die "$!:$file"; if ($run_in_fg){ print "($i/$num_files)Reading $file...\n";} while (my $line = <FILE>){ #don't need to actually print to screen, just load to memory } $total_size += -s $file; close FILE or die $!; $i++; } print_read_size($total_size); print "Complete!\n";
如果有更好的方法,请指出,谢谢!
2 个答案:
答案 0 :(得分:8)
open FILE, "<", $file or die "$!:$file";
此行尝试在当前目录中打开
$file
。具体来说,readdir
返回文件名,而不是路径。因此,必须在前面添加正确的路径:my $filepath = "$path/$file"; open FILE, "<", $filepath or die "$!:$filepath";
关于风格的评论:
my $i = 1; for my $file (@files){ ...; $i++; }
更好地表达为
for my $i (1 .. @files) { my $file = $files[$i - 1]; ...; }
而且
更改if
- 没有else
只包含一个表达式的条件可以从if (COND) {EXPR}
到
EXPR if COND;
我觉得更容易阅读。
接下来,
readdir
不会在文件名后附加换行符。因此,从文件名末尾删除换行符是不必要的,错误 - 这些可能是某些文件系统(1)中文件名的合法字符。所以$file =~ s/[\r\n]+$//;
是一个不必要的错误。
1:示例包括Ext2-Ext4系列(除
/
和\0
之外的所有字符),HFS(除:
以外的所有字符),Posix模式下的NTFS(全部除了/
和\0
)之外,Win32模式下的NTFS还禁止\
,*
,?
,:
,"
,<
,>
,|
。在perl5,v10及更高版本中,
print SOMETHING, "\n";
可以表示为
use feature 'say'; # or use VERSION where VERSION >= 5.10 say SOMETHING;
打开文件时,最好使用词法变量作为文件句柄:
open my $fh, "<", $filepath or die "$!:$filepath"; while(my $line = <$fh>) { ...; }
当引用计数降至零时,词法文件句柄会自动关闭。但是,明确关闭可能更适合更好的诊断。
答案 1 :(得分:1)
您需要在
$path
前加上readdir
的文件名前缀,例如my @files = grep { ! -d $_ } map { "$path/$_" } readdir $dir;
上面使用
$path
为所有目录条目添加前缀,并从结果中删除所有目录(因为您不想打开它们)。相关问题最新问题
- 我写了这段代码,但我无法理解我的错误
- 我无法从一个代码实例的列表中删除 None 值,但我可以在另一个实例中。为什么它适用于一个细分市场而不适用于另一个细分市场?
- 是否有可能使 loadstring 不可能等于打印?卢阿
- java中的random.expovariate()
- Appscript 通过会议在 Google 日历中发送电子邮件和创建活动
- 为什么我的 Onclick 箭头功能在 React 中不起作用?
- 在此代码中是否有使用“this”的替代方法?
- 在 SQL Server 和 PostgreSQL 上查询,我如何从第一个表获得第二个表的可视化
- 每千个数字得到
- 更新了城市边界 KML 文件的来源?