Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

readline on closed filehandle

by wrkrbeee (Scribe)
on Apr 14, 2016 at 18:50 UTC ( [id://1160441]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Perl Monks, the code below generates the infamous "readline on closed filehandle" error at line 42, which is while (my $doc = <$FH_IN>). A little digging seems to indicate that a faulty call is the culprit. I added a line to the code (immediately after the OPEN) to detect the current working directory. The input file is not in this directory ... yet I specified the input directory at the beginning of the program. Hence, I fail to understand why Perl is looking in a directory that differs from that specified in the code. Appreciate any insight! Thank you! UPDATE: Think I see the error, I'm closing the file before the while loop has a chance to cycle through the document. Need to close after the cycle is complete, which is at the end of the file. Am I right?

#!/usr/bin/perl -w use strict; use warnings; use File::stat; use lib "c:/strawberry/perl/site/lib"; #This program will extract Exhibit 21 info from 10-K filings; #Specify the directory containing the files that you want to read; my $files_dir = 'E:\research\audit fee models\filings\test'; #Specify the directory containing the results/output; my $write_dir = 'E:\research\audit fee models\filings\filenames\Exhib +it21.txt'; #Open the directory containing the files you plan to read; opendir(my $dir_handle, $files_dir) or die "Can't open directory $!"; #Initialize file counter variable; my $file_count = 0; #Loop for reading each file in the input directory; while (my $filename = readdir($dir_handle)) { next unless -f $files_dir.'/'.$filename; print "Processing $filename\n"; #Initialize the variable names. my $line_count=0; my $access_num=""; my $cik=-99; my $name=""; my $stuff=""; my $line=""; my $htm =""; #Open the input file; open my $FH_IN, '<',$files_dir.'/'.$filename or die "Can't open $fi +lename <:$!>"; use Cwd; print getcwd(), "\n"; #Within the file loop, read each line of the current file; $/="</DOCUMENT>"; while (my $doc = <$FH_IN>) { #Begin new document section; if ($doc =~ m/^\s*<FILENAME>(.*?)(ex21)/igm ) #if ($doc =~ m/^\s*<FILENAME>(.*?)(ex21)(.*?)(.htm$)/igm || # $doc =~ m/^\s*<FILENAME>(.*?)(EX-21)(.*?)(.htm$)/igm || # $doc =~ m/^\s*<FILENAME>(.*?)(ex21)(.*?)(.htm$)/igm || # $doc =~ m/^\s*<FILENAME>(.*?)(EX-21)(.*?)(.htm$)/igm) + { $htm=join('',$1,$2); } print $htm; #close $FH_IN or die "Cannot close $filename: $!"; close $FH_IN; #Open the ouput file; open my $FH_OUT, '>>',$write_dir or die "Can't open file $write_di +r >:$!>"; #Save the output to disk; print $FH_OUT "$htm\n"; #closedir($dir_handle); close($FH_OUT); } #end of document section; } #end of current file;

Replies are listed 'Best First'.
Re: readline on closed filehandle
by stevieb (Canon) on Apr 14, 2016 at 19:22 UTC

    Proper indentation and alignment is a very handy thing... you close the while loop on top of your close statement for the read file handle, which means it will read the first line (ie. entry), closes the file, then fails to read the next chunk because there's no more valid handle to read from.

    Is this more along the lines of what you're attempting to do (untested)?

    use strict; use warnings; use File::stat; use lib "c:/strawberry/perl/site/lib"; my $files_dir = 'E:\research\audit fee models\filings\test'; my $write_dir = 'E:\research\audit fee models\filings\filenames\Exhib +it21.txt'; open my $FH_OUT, '>>',$write_dir or die "Can't open file $write_dir >: +$!>"; opendir(my $dir_handle, $files_dir) or die "Can't open directory $!"; my $file_count = 0; while (my $filename = readdir($dir_handle)){ next unless -f $files_dir.'/'.$filename; print "Processing $filename\n"; my $line_count=0; my $access_num=""; my $cik=-99; my $name=""; my $stuff=""; my $line=""; my $htm =""; open my $FH_IN, '<',$files_dir.'/'.$filename or die "Can't open $f +ilename <:$!>"; use Cwd; print getcwd(), "\n"; $/="</DOCUMENT>"; while (my $doc = <$FH_IN>){ if ($doc =~ m/^\s*<FILENAME>(.*?)(ex21)/igm ){ $htm=join('',$1,$2); print $htm; print $FH_OUT "$htm\n"; } } close $FH_IN; } close($FH_OUT);
      Yes, that's much better. Thank you for your time!!

      Need to show my stupidity here, gotta ask ... the code below is the lower half of the cleanly aligned code you offered earlier (thanks again there!). Pgm runs, but no output. So, I began tinkering with my REGEX to no avail. Now I'm looking at the code and here's what my feeble mind sees .... first, we set $/ (the delimiter) to </DOCUMENT>. Thus, we should process data until we discover this delimiter, at which point we write the data to disk, then begin processing anything after </DOCUMENT> up until the next occurrence of </DOCUMENT>. Is that right? If so, then as a diagnostic tool, should I be able to print (to the screen) the contents of the data between the delimiters? If so, which variable will contain this data? Sorry for the neophyte-like questions. Thank you. UPDATE: Withdrawn, problem solved. Sorry!

      open my $FH_IN, '<',$files_dir.'/'.$filename or die "Can't open $filen +ame <:$!>"; use Cwd; print getcwd(), "\n"; $/="</DOCUMENT>"; while (my $doc = <$FH_IN>) { if ($doc =~ m/^\s*<FILENAME>\s*(.*)(ex21)\s*(.*)(<\/TEXT)\s*(.* +)/igm || $doc =~ m/^\s*<FILENAME>\s*(.*)(EX\-21)\s*(.*)(<\/TEXT)\s*( +.*)/igm ) { $htm=join('',$1); print $htm; print $FH_OUT "$htm\n"; } } close $FH_IN; } close($FH_OUT);

        It would be appreciated if you would share what you did to correct your mistake/misunderstanding, so that future readers will learn as well.

Re: readline on closed filehandle
by choroba (Cardinal) on Apr 14, 2016 at 19:13 UTC
    Your update is correct. You close the handle on line 55 after processing the first line.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (7)
As of 2024-04-19 11:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found