为什么我的文件处理程序是空的?? PERL
Why is my filehandler empty?? PERL
我是 Perl 的新手,我有一段代码返回一个空的文件处理程序。
my $md5dir = "...plib/test/md5sum"; #IN MY PROG, IS THE FULL PATH
opendir( DIR, $md5dir ) or die "Can't open directory $md5dir: $!";
my @md5files = grep !/^\.\.?$/, readdir(DIR);
closedir(DIR);
if ( scalar @md5files < 1
|| scalar @md5files > 8
|| ( scalar @md5files % 2 != 0 ) )
{
print "Incorrect amount of files in directory. Aborting.\n";
exit 1;
}
else {
for ( my $i = 0; ( $i < scalar @md5files / 2 ); $i++ ) {
my $file1 = $md5files[$i];
open( my $fh1, $file1 ) or die "Fail to open file $file1 $!";
my $file2 = $md5files[ $i + 3 ];
open( my $fh2, $file2 ) or die "Fail to open file $file2 $!";
print "2.", $file1, " ", $file2, "\n";
my $first1 = substr( $file1, 0, 4 );
my $first2 = substr( $file2, 0, 4 );
if ( ( $first1 cmp $first2 ) == 0 ) {
if ( eof $fh1 ) { print "No lines\n"; }
else { my $line1 = <$fh1>; print "$line1\n"; }
if ( eof $fh2 ) { print "No lines2\n"; }
else { my $line2 = <$fh2>; print "$line2\n"; }
close $fh1;
close $fh2;
}
} # for
} # else
输出是这样的:
2.SAM5_27-04-2016_11:21:20.md5 SAM5_27-04-2016_11:20:11.md5
No lines
No lines2
2.SAM6_27-04-2016_11:18:25.md5 SAM6_25-04-2016_10:38:38.md5
No lines
No lines2
2.SAM4_27-04-2016_11:19:06.md5 SAM4_27-04-2016_11:17:22.md5
No lines
No lines2
在 md5sum 的目录中:
:md5sum>ls -la
total 16
drwxrwxr-x 2 ateam ateam 4096 Apr 27 11:24 ./
drwxrwxr-x 4 ateam ateam 4096 Apr 27 11:24 ../
-rw-rw-r-- 1 ateam ateam 63 Apr 27 11:17 SAM4_27-04-2016_11:17:22.md5
-rw-rw-r-- 1 ateam ateam 63 Apr 27 11:19 SAM4_27-04 2016_11:19:06.md5
-rw-rw-r-- 1 ateam ateam 63 Apr 27 11:20 SAM5_27-04-2016_11:20:11.md5
-rw-rw-r-- 1 ateam ateam 0 Apr 27 11:21 SAM5_27-04-2016_11:21:20.md5
-rw-rw-r-- 1 ateam ateam 63 Apr 25 10:38 SAM6_25-04-2016_10:38:38.md5
-rw-rw-r-- 1 ateam ateam 63 Apr 27 11:18 SAM6_27-04-2016_11:18:25.md5
有人可以解释为什么文件处理程序是空的吗?我验证了文件的打印。它们都很好地打印到数组中并且文件处理程序正在打开......因为文件不是空的,还有什么可能是错的??? (好吧,除了那个……)
只是为了查看文件...以防万一。
打开我得到的第一个文件:
03c0cf2ab0da62832bfc6970d4505746 SAM4_27-04-2016_11:17:22.csv
编辑:::
我对文件做了轻微的调整:
if (($first1 cmp $first2) == 0) {
if (tell($fh1) == -1){ print "No lines\n";}
else {my $line1= <$fh1>; print "$line1\n"; }
if (eof $fh2){ print "No lines2\n";}
else { my $line2= <$fh2>; print "$line2\n"; }
close $fh1; close $fh2;
}
并得到了这个输出:
2.SAM5_27-04-2016_11:21:20.md5 SAM5_27-04-2016_11:20:11.md5
Use of uninitialized value in concatenation (.) or string at mulftptest line 53.
No lines2
2.SAM6_27-04-2016_11:18:25.md5 SAM6_25-04-2016_10:38:38.md5
Use of uninitialized value in concatenation (.) or string at mulftptest line 53.
No lines2
2.SAM4_27-04-2016_11:19:06.md5 SAM4_27-04-2016_11:17:22.md5
Use of uninitialized value in concatenation (.) or string at mulftptest line 53.
No lines2
基本上,我知道这是在告诉我我正在尝试使用 "empty" 变量。但是,我不明白为什么它是空的。
主要问题是readdir
return只有文件名,没有任何路径信息
这意味着您在当前工作目录中打开 SAM5_27-04-2016_11:21:20.md5
,而不是在 md5sum
目录中。通常你的 open 调用会失败,但你的脚本目录中似乎有同名的虚假空文件
如果您像这样编写公开调用,那么它应该适合您
open my $fh1, '<', "$md5dir/$file1" or die "Fail to open file $file1: $!";
并且不要为此目的使用 tell
。无论文件是否为空,它都会在开始时 return 归零。你真的想要 -s $fh1
其中 returns 文件的字节大小,并且可以用在文件名或打开的文件句柄上
我最好的猜测是您需要这样的东西。我很确定你有一个包含 MD5 校验和的文件目录并且想比较它们
我通过这些方式使这更简单
我在程序的顶部有 use autodie
。这是一个检查大多数 Perl IO 操作的 pragma,并使您无需验证每个 open
调用是否成功。它被引入核心 perl v5.10.1 并且是可靠的
我添加了一个use constant
作为MD5文件目录的路径
我使用 glob
而不是 opendir
/ readdir
来查找 md5sum
目录中以 .md5
结尾的所有文件. glob
永远不会 return 伪目录 .
和 ..
,但如果有人感到奇怪,xx.md5
总是有可能是一个目录。您可能想要添加支票
有一个循环来构建一个散列,该散列将每个 "prefix"(前缀是文件名中第一个下划线之前的所有字符)与每个具有该前缀的文件相关联
检查该散列以确保目录中的每个前缀都有准确的文件。这似乎与原始支票一致
现在有了一个将每个前缀与两个文件相关联的散列,问题似乎就解决了。我的代码显示每个前缀及其两个文件的名称和它们包含的 MD5 字符串
use strict;
use warnings 'all';
use autodie;
use constant MD5_DIR => '...plib/test/md5sum'; #IN YOUR PROG, IS THE FULL PATH
chdir MD5_DIR;
my %files;
# Build a hash of files collected by prefix
#
for my $file ( glob '*.md5' ) {
next unless my ($prefix) = $file =~ / ^ ( [^_]+ ) /x;
push @{ $files{$prefix} }, $file;
}
# Check that there are exactly two files with each prefix
#
{
my $errors;
while ( my ($prefix, $files) = each %files ) {
my $n = @$files;
if ( @$files != 2 ) {
warn qq{$n files fouhd for prefix "${prefix}_"\n};
++$errors;
}
}
die "Dying because errors found in source directory" if $errors;
}
# Display every pair of files by prefix
#
while ( my ($prefix, $files) = each %files ) {
my ($file1, $file2) = sort @$files;
print "Prefix: $prefix\n";
for my $file ( sort @$files ) {
open my $fh, '<', $file;
my $md5 = <$fh>;
$md5 =~ s/\s+\z//;
print " File: $file\n";
print " MD5: $md5\n";
}
}
我是 Perl 的新手,我有一段代码返回一个空的文件处理程序。
my $md5dir = "...plib/test/md5sum"; #IN MY PROG, IS THE FULL PATH
opendir( DIR, $md5dir ) or die "Can't open directory $md5dir: $!";
my @md5files = grep !/^\.\.?$/, readdir(DIR);
closedir(DIR);
if ( scalar @md5files < 1
|| scalar @md5files > 8
|| ( scalar @md5files % 2 != 0 ) )
{
print "Incorrect amount of files in directory. Aborting.\n";
exit 1;
}
else {
for ( my $i = 0; ( $i < scalar @md5files / 2 ); $i++ ) {
my $file1 = $md5files[$i];
open( my $fh1, $file1 ) or die "Fail to open file $file1 $!";
my $file2 = $md5files[ $i + 3 ];
open( my $fh2, $file2 ) or die "Fail to open file $file2 $!";
print "2.", $file1, " ", $file2, "\n";
my $first1 = substr( $file1, 0, 4 );
my $first2 = substr( $file2, 0, 4 );
if ( ( $first1 cmp $first2 ) == 0 ) {
if ( eof $fh1 ) { print "No lines\n"; }
else { my $line1 = <$fh1>; print "$line1\n"; }
if ( eof $fh2 ) { print "No lines2\n"; }
else { my $line2 = <$fh2>; print "$line2\n"; }
close $fh1;
close $fh2;
}
} # for
} # else
输出是这样的:
2.SAM5_27-04-2016_11:21:20.md5 SAM5_27-04-2016_11:20:11.md5
No lines
No lines2
2.SAM6_27-04-2016_11:18:25.md5 SAM6_25-04-2016_10:38:38.md5
No lines
No lines2
2.SAM4_27-04-2016_11:19:06.md5 SAM4_27-04-2016_11:17:22.md5
No lines
No lines2
在 md5sum 的目录中:
:md5sum>ls -la
total 16
drwxrwxr-x 2 ateam ateam 4096 Apr 27 11:24 ./
drwxrwxr-x 4 ateam ateam 4096 Apr 27 11:24 ../
-rw-rw-r-- 1 ateam ateam 63 Apr 27 11:17 SAM4_27-04-2016_11:17:22.md5
-rw-rw-r-- 1 ateam ateam 63 Apr 27 11:19 SAM4_27-04 2016_11:19:06.md5
-rw-rw-r-- 1 ateam ateam 63 Apr 27 11:20 SAM5_27-04-2016_11:20:11.md5
-rw-rw-r-- 1 ateam ateam 0 Apr 27 11:21 SAM5_27-04-2016_11:21:20.md5
-rw-rw-r-- 1 ateam ateam 63 Apr 25 10:38 SAM6_25-04-2016_10:38:38.md5
-rw-rw-r-- 1 ateam ateam 63 Apr 27 11:18 SAM6_27-04-2016_11:18:25.md5
有人可以解释为什么文件处理程序是空的吗?我验证了文件的打印。它们都很好地打印到数组中并且文件处理程序正在打开......因为文件不是空的,还有什么可能是错的??? (好吧,除了那个……)
只是为了查看文件...以防万一。 打开我得到的第一个文件:
03c0cf2ab0da62832bfc6970d4505746 SAM4_27-04-2016_11:17:22.csv
编辑::: 我对文件做了轻微的调整:
if (($first1 cmp $first2) == 0) {
if (tell($fh1) == -1){ print "No lines\n";}
else {my $line1= <$fh1>; print "$line1\n"; }
if (eof $fh2){ print "No lines2\n";}
else { my $line2= <$fh2>; print "$line2\n"; }
close $fh1; close $fh2;
}
并得到了这个输出:
2.SAM5_27-04-2016_11:21:20.md5 SAM5_27-04-2016_11:20:11.md5
Use of uninitialized value in concatenation (.) or string at mulftptest line 53.
No lines2
2.SAM6_27-04-2016_11:18:25.md5 SAM6_25-04-2016_10:38:38.md5
Use of uninitialized value in concatenation (.) or string at mulftptest line 53.
No lines2
2.SAM4_27-04-2016_11:19:06.md5 SAM4_27-04-2016_11:17:22.md5
Use of uninitialized value in concatenation (.) or string at mulftptest line 53.
No lines2
基本上,我知道这是在告诉我我正在尝试使用 "empty" 变量。但是,我不明白为什么它是空的。
主要问题是readdir
return只有文件名,没有任何路径信息
这意味着您在当前工作目录中打开 SAM5_27-04-2016_11:21:20.md5
,而不是在 md5sum
目录中。通常你的 open 调用会失败,但你的脚本目录中似乎有同名的虚假空文件
如果您像这样编写公开调用,那么它应该适合您
open my $fh1, '<', "$md5dir/$file1" or die "Fail to open file $file1: $!";
并且不要为此目的使用 tell
。无论文件是否为空,它都会在开始时 return 归零。你真的想要 -s $fh1
其中 returns 文件的字节大小,并且可以用在文件名或打开的文件句柄上
我最好的猜测是您需要这样的东西。我很确定你有一个包含 MD5 校验和的文件目录并且想比较它们
我通过这些方式使这更简单
我在程序的顶部有
use autodie
。这是一个检查大多数 Perl IO 操作的 pragma,并使您无需验证每个open
调用是否成功。它被引入核心 perl v5.10.1 并且是可靠的我添加了一个
use constant
作为MD5文件目录的路径我使用
glob
而不是opendir
/readdir
来查找md5sum
目录中以.md5
结尾的所有文件.glob
永远不会 return 伪目录.
和..
,但如果有人感到奇怪,xx.md5
总是有可能是一个目录。您可能想要添加支票
有一个循环来构建一个散列,该散列将每个 "prefix"(前缀是文件名中第一个下划线之前的所有字符)与每个具有该前缀的文件相关联
检查该散列以确保目录中的每个前缀都有准确的文件。这似乎与原始支票一致
现在有了一个将每个前缀与两个文件相关联的散列,问题似乎就解决了。我的代码显示每个前缀及其两个文件的名称和它们包含的 MD5 字符串
use strict;
use warnings 'all';
use autodie;
use constant MD5_DIR => '...plib/test/md5sum'; #IN YOUR PROG, IS THE FULL PATH
chdir MD5_DIR;
my %files;
# Build a hash of files collected by prefix
#
for my $file ( glob '*.md5' ) {
next unless my ($prefix) = $file =~ / ^ ( [^_]+ ) /x;
push @{ $files{$prefix} }, $file;
}
# Check that there are exactly two files with each prefix
#
{
my $errors;
while ( my ($prefix, $files) = each %files ) {
my $n = @$files;
if ( @$files != 2 ) {
warn qq{$n files fouhd for prefix "${prefix}_"\n};
++$errors;
}
}
die "Dying because errors found in source directory" if $errors;
}
# Display every pair of files by prefix
#
while ( my ($prefix, $files) = each %files ) {
my ($file1, $file2) = sort @$files;
print "Prefix: $prefix\n";
for my $file ( sort @$files ) {
open my $fh, '<', $file;
my $md5 = <$fh>;
$md5 =~ s/\s+\z//;
print " File: $file\n";
print " MD5: $md5\n";
}
}