我正在编写一个只读取文件的脚本.我遇到的一个问题是,如果我传入路径(使用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 Bs
完成!
我真的不明白为什么我会这样做.权限问题?
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";
Run Code Online (Sandbox Code Playgroud)
如果有更好的方法,请指出,谢谢!
open FILE, "<", $file or die "$!:$file";
Run Code Online (Sandbox Code Playgroud)
此行尝试打开$file- 在当前目录中.具体来说,readdir返回文件名,而不是路径.因此,必须在前面添加正确的路径:
my $filepath = "$path/$file";
open FILE, "<", $filepath or die "$!:$filepath";
Run Code Online (Sandbox Code Playgroud)
my $i = 1;
for my $file (@files){
...;
$i++;
}
Run Code Online (Sandbox Code Playgroud)
更好地表达为
for my $i (1 .. @files) {
my $file = $files[$i - 1];
...;
}
Run Code Online (Sandbox Code Playgroud)
并且if没有else包含一个表达式的条件可以从中更改
if (COND) {EXPR}
Run Code Online (Sandbox Code Playgroud)
至
EXPR if COND;
Run Code Online (Sandbox Code Playgroud)
我发现更容易阅读.
接下来,readdir不会在文件名后附加换行符.因此,从文件名末尾删除换行是不必要的和错误的 - 这些可能是某些文件系统中文件名的合法字符(1).所以
$file =~ s/[\r\n]+$//;
Run Code Online (Sandbox Code Playgroud)
是一个不必要的错误.
1:实施例包括的Ext2-的Ext4家族(除所有字符/和\0),HFS(除所有字符:),NTFS中的Posix模式(除了/和\0),并在Win32的模式NTFS另外不允许\,*,?,:,",<,>,|.
在perl5,v10及更高版本中,
print SOMETHING, "\n";
Run Code Online (Sandbox Code Playgroud)
可以表达为
use feature 'say'; # or use VERSION where VERSION >= 5.10
say SOMETHING;
Run Code Online (Sandbox Code Playgroud)
打开文件时,最好使用词法变量作为文件句柄:
open my $fh, "<", $filepath or die "$!:$filepath";
while(my $line = <$fh>) {
...;
}
Run Code Online (Sandbox Code Playgroud)
当引用计数降至零时,词法文件句柄将自动关闭.但是,明确关闭可能更适合更好的诊断.