ckj has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, please check the code as it's working fine for hard coded path but for generic path it's not working, it says "Can't read the file". Please check and let me know where am I lagging:
#!/usr/bin/perl use warnings; use strict; print "Enter the path where the log file is placed : "; my $dir =<>; chomp($dir); opendir DIR, $dir or die "cannot open dir $dir: $!"; my @files= readdir DIR; my $len=scalar(@files); print $len; print "Enter the path where to save the report"; my $dest_dir = <STDIN>; chomp($dest_dir); open(FH1,">$dest_dir./result.txt") if( $len > 0); foreach my $file (@files){ if($file=~/\.txt/){ print "$file\n"; open(FH,"$file") or die "Can't read the file \n"; while(my $line= <FH> ){ print FH1 $line; } close FH; } } close FH1; closedir DIR;
UPDATE: My program is in C:\Perl\bin and I'm entering the path to read & write files as C:\Perl where it gets failed but if I use C:\Perl\bin then it works fine. How to fix this issue?

Replies are listed 'Best First'.
Re: Unable to read a file
by tobyink (Canon) on Jun 13, 2012 at 06:59 UTC

    I assume this is the culprit:

    ">$dest_dir./result.txt"

    What is that dot doing in there?

    But yes, you should always check the success of open and handle failures (usually with something like or die "cannot open '$filename': $!").

    Or use autodie.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Unable to read a file
by rovf (Priest) on Jun 13, 2012 at 06:52 UTC
    You should output $!, and also the name of the file, if opening the file fails.

    -- 
    Ronald Fischer <ynnor@mm.st>
Re: Unable to read a file
by pvaldes (Chaplain) on Jun 13, 2012 at 08:44 UTC

    Similar but a little more compact

    #!/usr/bin/perl -w use strict; use autodie; print "Enter the path where the log file is placed: "; chomp(my $dir = <STDIN>); opendir DIR, $dir; my @text = grep (/\.txt$/, readdir DIR); # <--- note the '$' here closedir DIR; print "Enter the path where to save the report: "; chomp(my $dest_dir = <STDIN>); open (my $FH1, '>', "$dest_dir/result.txt") if( scalar(@text) > 0); foreach my $textfile (@text){ print $FH1 $textfile,"\n"; } close $FH1;
Re: Unable to read a file
by ckj (Chaplain) on Jun 13, 2012 at 07:13 UTC
    thanks rovf I got the issue by printing $!
    #!/usr/bin/perl use warnings; use strict; print "Enter the path where the log file is placed : "; my $dir =<>; chomp($dir); opendir DIR, $dir or die "cannot open dir $dir: $!"; my @files= readdir DIR; my $len=scalar(@files); print $len; print "Enter the path where to save the report"; my $dest_dir = <STDIN>; chomp($dest_dir); open(FH1,">$dir./result.txt") if( $len > 0); foreach my $file (@files){ if($file=~/\.txt/){ print "$file\n"; open(FH,"$dest_dir./$file") or die $!; while(my $line= <FH> ){ print FH1 $line; } close FH; } } close FH1; closedir DIR;
    Any other suggestions or feedbacks on this are welcome. Thanks everyone.

      It appears you changed the line

      open(FH,"$file") or die "Can't read the file\n";

      to

      open(FH,"$dest_dir./$file") or die $!;

      However, you read the files from $dir not $dest_dir, so obviously they will not be found.

      Also, you do not need the period/dot:

      open(FH,"$dir/$file") or die $!;

      As mentioned before, get rid of the period/dot on this line:

      open(FH1,">$dest_dir./result.txt") if( $len > 0);

      Should be

      open(FH1,">$dest_dir/result.txt") if( $len > 0);

      Or better yet, use the three argument form of open:

      open(FH1,'>',"$dest_dir/result.txt") if( $len > 0);

      Of course it would be good if you checked whether the open failed or not.

      HTH, Ken

Re: Unable to read a file
by morgon (Priest) on Jun 13, 2012 at 16:57 UTC
    Also note that your my $dir =<>; is not quite the same as your my $dest_dir = <STDIN>;.

    If you run your script without arguments it will read from STDIN, but if you supply arguments it will treat your arguments as filenames and read from them.

    This may or may not be what you want (ususally it's a bug).