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

Hey Monks!

So it seems like every time write a script that reads and writes to a file I get this error:

print() on closed filehandle DATA_1 at compare_names.pl line 33, <SECO +ND> line 773874

The error above is specific for the code below, but none the less it's telling me the same thing. If you have any ideas on how to stop the compiler from yelling at me all the time I would greatly appreciate it! Thank you very much!


#! usr/bin/perl -w use strict; use warnings; print "What is the filepath of Jay's file?\n"; my $first_file = <STDIN>; print "And the mine?\n"; my $second_file = <STDIN>; open FIRST, $first_file; open SECOND, $second_file; open DATA_1, "</home/Alan/Desktop/sequence_data/sequence_comparison/Ja +ys_unique.txt"; #open DATA_2, "/home/Alan/Desktop/sequence_data/sequence_comparison/my +_unique_results.txt"; while(<FIRST>){ my $name_1 = $_; my $match = 0; while(<SECOND>){ my $name_2 = $_; if($name_1 eq $name_2){ $match = 1; last; } } if($match != 1){ print DATA_1 $name_1,"\n"; } } close FIRST; close SECOND; close DATA_1;

Replies are listed 'Best First'.
Re: print() on Closed File Handle Error!
by Fletch (Bishop) on Aug 13, 2010 at 18:36 UTC

    Don't try and use an invalid filehandle. You always should check the return value from system calls such as open to find out if they failed or not before trying to use their products.

    open FIRST, $first_file or die "Can't open '$first_file' for reading: +$!\n";

    Update: Also printing to a filehandle opened for reading doesn't make much sense (even if it opened successfully). You need to (re)read perlopentut.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: print() on Closed File Handle Error!
by kennethk (Abbot) on Aug 13, 2010 at 18:42 UTC
    Why are your opening an output file as an input (the leading < on the file name)? You should be testing every open, and I suspect this is failing on open because your output file does not exist yet. Please swap your lines 11-13 to:

    open FIRST, $first_file or die "Open failed: $!"; open SECOND, $second_file or die "Open failed: $!"; open DATA_1, "</home/Alan/Desktop/sequence_data/sequence_comparison/Ja +ys_unique.txt" or die "Open failed: $!";

    to see why the handle isn't open, and then swap the intent on your DATA_1 handle to get the proper behavior:

    open DATA_1, '>', "/home/Alan/Desktop/sequence_data/sequence_comparison/Jays_unique.txt" or die "Open failed: $!";

    Please read perlopentut to get some good ideas on how to properly approach this sort of operation.

Re: print() on Closed File Handle Error!
by twaddlac (Novice) on Aug 13, 2010 at 18:59 UTC

    Ah that helps! Printing out the error message is what I needed! I was assuming that the filehandle would automatically create the file to write to, and it didn't hence the error message. Thank you very much you guys! Now I know what to do next time! :-)

      I still think you are missing a very important point, so I'll just reiterate it here.

      Opening a file for writing will automatically create the file if necessary. But you are not opening the file for writing (>), you are opening it for reading (<). Please read the docs and make sure you understand the different modes used by open.

          I was assuming that the filehandle would automatically create the file to write to, and it didn't hence the error message.

      If that's what you're trying to do, you'll need to use the '>>' mode for open, which will create the file if it doesn't exist and destroy the contents if it does exist. Still, even when I have used this mode in my scripts, I still include the die statement and would recommend that you do so too. Very useful in debugging issues as you have just learned.

        That is incorrect. As is states in open

        If three or more arguments are specified then the mode of opening and the filename are separate. If MODE is '<' or nothing, the file is opened for input. If MODE is '>' , the file is truncated and opened for output, being created if necessary. If MODE is '>>' , the file is opened for appending, again being created if necessary.

        Both > and >> will create a file. > empties the file and >> appends. Your post has that backwards.

        You should always have a check whether an file open worked - that's true for any language! In Perl we use the construct "or die". There a many ways that an open can fail some common ones besides name or path wrong: disk quota exceeded, don't have the right permissions to do what you are trying to do, file is already open by somebody else and the list goes on and on with all sorts of "yeah but's".