Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

How to open files found via File::Find

by Anonymous Monk
on Jan 08, 2010 at 00:17 UTC ( [id://816193]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks,

I'm trying trying to process all .dat files in a nested directory tree. I've used the File::Find module but it's not working how I expected it to work. I can't even concatenate the directory and the filename to open the files. I always get the error message "readline() on closed filehandle"

Any help would be deeply appreciated!

Here is the code:

use strict; use warnings; use Cwd; my $startdirectory = cwd; print "Starting directory: $startdirectory\n"; use File::Find; find ( \&inFiles, ('.') ); exit; sub inFiles { chomp; my $name = $_; my $directory = cwd; if( $name =~ /.dat/) { print "dir = $directory\tname = $name\n"; open INFILE,'<$name' || warn ("Cannot open input file $name\n"); my @infilecontent = <INFILE>; print @infilecontent; my $localfile = "$directory\$name"; #win32 open INFILE2,'<$localfile' || warn ("Cannot open input file $localf +ile\n"); @infilecontent = <INFILE2>; print @infilecontent; } } #inFiles

Replies are listed 'Best First'.
Re: How to open files found via File::Find
by ikegami (Patriarch) on Jan 08, 2010 at 00:30 UTC
    • You're not getting the errors you should because

      open INFILE,'<$name' || warn ("Cannot open input file $name\n");
      means
      open INFILE, ( '<$name' || warn ("Cannot open input file $name\n") );
      which is the same as the following (since '<$name' is always true):
      open INFILE, '<$name'

      You want to use parens or lower-precedence "or":

      open(INFILE, '<$name') || warn ("Cannot open input file $name\n");
      or
      open INFILE, '<$name' or warn ("Cannot open input file $name\n");
    • Then there's the problem that '<$name' produces the five character < $ n a m e. You need to use double-quote to interpolate.

      open(INFILE, "<$name") or warn ("Cannot open input file $name\n");
      Or better yet, use the safer, more reliable 3-arg open:
      open(INFILE, '<', $name) or warn("Cannot open input file $name: $!\n");
    • Finally, $_ only contains the name of the file, not the path to the file. You need to use $File::Find::name.

      open(INFILE, '<', $File::Find::name) or warn("Cannot open input file $File::Find::name: $!\n");
    • There's also a problem with

      "$directory\$name"

      The backslash before the $ tells Perl to treat the $ as a non-special character. You want

      "$directory\\$name"

      The following would also be fine:

      "$directory/$name"

      Yes, even on Windows. Windows accepts both slashes.

      Finally, $_ only contains the name of the file, not the path to the file. You need to use $File::Find::name.

      Actually, File::File::find() changes directories while tranversing the file system so $_ doesn't need the path because $_ is in the CWD (which is in $File::Find::dir).

Re: How to open files found via File::Find
by gam3 (Curate) on Jan 08, 2010 at 00:33 UTC
    You are using single quotes in you open statements. try
    open INFILE2,'<', $localfile ...
    and you should have better luck. You also need 2 backslashes in a double quoted string. Or use $directory . '\' . $name.
    use strict; use warnings; use Cwd; my $startdirectory = cwd; print "Starting directory: $startdirectory\n"; use File::Find; find ( \&inFiles, ('.') ); exit; sub inFiles { chomp; my $name = $_; my $directory = cwd; if ( $name =~ /.dat/) { print "dir = $directory\tname = $name\n"; open INFILE,'<', "$directory/$name" || warn ("Cannot open input fil +e $name\n"); my @infilecontent = <INFILE>; print length @infilecontent; my $localfile = "$directory\\$name"; #win32 open INFILE2,'<', $localfile || warn ("Cannot open input file $loca +lfile\n"); @infilecontent = <INFILE2>; print @infilecontent; } } #inFiles
    -- gam3
    A picture is worth a thousand words, but takes 200K.

      For better portability, I'd suggest using "/" rather than "\\" as a directory separator.

      ...roboticus

        Or even better use File::Spec->catfile.
        -- gam3
        A picture is worth a thousand words, but takes 200K.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://816193]
Approved by gam3
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2024-03-29 12:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found