Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Why do we need to close filehandles?

by tej (Scribe)
on Apr 30, 2011 at 05:07 UTC ( #902128=perlquestion: print w/ replies, xml ) Need Help??
tej has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I had a question about filehandles. Why is it neccesary to close filehadles? What happens if we open file and dont close the filehandle?

I read somewhere that file will corrupt, however I tried doing it and my script dies in between saying illegal division by 0. Still i could access file later and nothing happended to it?..

And what happens to this filehandle? As we have not closed it properly? Where does it go?

Comment on Why do we need to close filehandles?
Re: Why do we nned to close filehandles?
by kejohm (Hermit) on Apr 30, 2011 at 05:32 UTC

    Perl will usually automatically close any open file handles at the end of the script, so most of the time, you don't have to bother. The only trouble comes when you need to open a large number of files concurrently. Most operating systems have a limited number of file handles available, so if you fail to close any open file handles, you may run out, which isn't easy to recover from. Conveniently, in newer versions of Perl, storing a file handle in a lexical variable will cause the file handle to be automatically closed when the variable goes out of scope, e.g.

    if(open my $fh, '<', $file){ # process file } # file will be closed when we reach here

    Check out open and close for more info.

    Update: Links fixed.

      FileCache - keep more files open than the system permits
Re: Why do we nned to close filehandles?
by Anonymous Monk on Apr 30, 2011 at 05:32 UTC
    I had a question about filehandles. Why is it neccesary to close filehadles?

    Imagine a filehandle as a door or lid of some sort, closeing the lid flushes the filehandle.

    What happens if we open file and dont close the filehandle?

    The filehandle remains open until the end of scope, or in the case of global filehandles, until the end of the program (die / exit / or else)

    Where does it go?

    It runs to the bitbucket.

Re: Why do we nned to close filehandles?
by wind (Priest) on Apr 30, 2011 at 06:42 UTC

    Most of the time you'll be fine if you don't explicitly close your find handles.

    However, if you do any further operations on that file before closing, you could end up with unexpected results.

    There was actually a case recently where someone was trying to serve a dynamic pdf from apache. They wrote it to a file and then had apache serve the file. Unfortunately, they didn't close the file handle before passing it to apache so their downloaded pdf was always malformed.

    The lesson is always close your file handles and/or use lexical file handles so they are closed when they go out of scope.

      Filehandles are closed automatically at the end of script but if script teminates abruptly giving some error then what happens?..

      downloaded pdf was always malformed : does it affect txt files as well?.. Or just some formats are affected?

        Filehandles are closed automatically at the end of script but if script teminates abruptly giving some error then what happens?..

        They go the the bit bucket.

        downloaded pdf was always malformed : does it affect txt files as well?.. Or just some formats are affected?

        Dear tej, incomplete file is incomplete :) please read Filehandle, File Handles (Windows)

Re: Why do we need to close filehandles?
by choroba (Abbot) on Apr 30, 2011 at 10:43 UTC
    Recently, a student of mine had a problem: in his program, he was creating a file. Later in the program, he was reading the file - but he did not close its file handle, which resulted in the file not being complete. The program thus returned wrong results.

      Bingo!   There’s a solid technical reason for paying close attention to file-handles ... buffering.   Until a file-handle is closed, it is possible that there’s some data out there which has not been written to disk.   Other applications will not see that data yet; nor will this application, necessarily, if it opens a second handle to the same file.   (Which it is, of course, free to do.)

      Obviously, the system will wipe your a*s ... clean up after you even if you don’t, but writing to a file is an action that you need to explicitly bring to a close.   Reading from the file is much more forgiving.

        There’s a solid technical reason for paying close attention to file-handles ... buffering.
        Well, you can just flush the handle; there's no need to close it. And if you do things in a logical way, you either read/write using buffered I/O, or you read/write using unbuffered I/O. In either case, you should be fine.
Re: Why do we need to close filehandles?
by shawnhcorey (Pilgrim) on Apr 30, 2011 at 13:22 UTC

    You close your files as soon as possible so that you can check for errors. This is needful especially when writing.

    close $fh or die "could not close file: $!\n";
Re: Why do we need to close filehandles?
by afoken (Parson) on Apr 30, 2011 at 14:32 UTC

    In addition to what others said:

    Filehandles are a limited resource. Typically, a process is limited to 20 to about 200 file handles, trying to open more handles will result in errors. The reason for this limit is that file handles have a price. The OS needs to allocate some memory for the file meta-data (where on the disk is the file, at what offset will data be read/written, and so on) and some more memory for the file contents. Unwritten data has to be buffered in memory, because disk writes and even flash writes are waaaaay slower than writing to RAM. So every common OS attempts to write only when really needed, preferably without blocking the entire system.

    Aborting a program which still has file handles opened is unpredictable, because the libc can also buffers data, in addition to the operating system. Wheather or not the data buffered in the libc ends in the file depends on how the libc is implemented and how the program is aborted. Therefore, the general advice is to keep files opened as short as possible, so that libc and OS can flush their buffers to the disk.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      As a complete “aside point,” I normally do not ask my applications to “flush buffered data to disc.”   If you want to see just how badly this can affect performance (albeit with a perfectly good reason in this case), try using an SQLite database without using transactions.   Just let the data sit in the operating-system buffers as it normally does, and basically just let the OS do its thing.   But, when you have reached a logical end-point in whatever it is that you are doing, explicitly inform the operating system that you have done so, by closing the file.

      Writes to things like flash-cards can be astonishingly slow, continuing for many seconds after the application has closed.   That is why it is paramount to drill-in to your users that they must dismount the cards, and wait for that process to finish, before removing the cards from the USB port.   (You’ve got maybe a 50% chance that your grandmother will actually listen to you, but maybe that’s better than nothing.)

        Or wait for the light on the device to change state, like an old school floppy drive.

        But that's not 100% guaranteed.

Re: Why do we need to close filehandles?
by cdarke (Prior) on Apr 30, 2011 at 18:14 UTC
    Usually you don't have to (edge cases aside), but it is a good developer's mindset to release resources as soon as possible, so these can be used by other processes, and to reduce the load on the system. That is all resources, not just files.

    Personally if I don't close a file it does not feel right - a bit like walking out the door without my trousers on.
      Personally if I don't close a file it does not feel right - a bit like walking out the door without my trousers on.
      Yeah, but you still didn't flush.

      Why do feel dirty if you don't close the file yourself (instead of having Perl do it for you), but you're fine with Perl doing the flushing (and syncing) for you? And do you close STDOUT and STDERR?

      I close my handles when I want to inform the user of a possible error - else I let Perl (or the OS) take care of it for me.

        I know what he means; I had to double check the zipper myself until I learned to trust that leaving the scope of the bathroom would ensure it for me.

        Part of the issue might be being used to places where there are no bathroom walls, and bits are deposited just anywhere.

Re: Why do we need to close filehandles?
by davido (Archbishop) on May 01, 2011 at 21:38 UTC

    Lots of sage advice. Now for a brief summary:

    • Closing a filehandle forces a flush of the buffer.
    • Closing a filehandle releases the filehandle resource.
    • Closing a filehandle allows for a final check to ensure that things worked as planned. (or die $!)
    • Closing a filehandle improves code readability. It tells future readers "I'm done with that."
    • Closing filehandles improves code portability to platforms such as mod_perl where perl never actually terminates.
    • Closing filehandles reduces errors at a distance (This relates to the 'or die' list item).

    Closing read-only filehandles doesn't really run the risk of buffering or 'final check' problems. But it does still relate to resource usage, portability, and readability.


    Dave

      Thaks, Everybody, I got it now..
Re: Why do we need to close filehandles?
by GrandFather (Cardinal) on May 03, 2011 at 06:02 UTC

    One technique that can help manage the time a file is open is to use lexical file handles:

    ... { open my $fileIn, '<', $filename or die "Failed to open $filename: +$!\n"; ... }

    The end of the enclosing block (the '}') is the place where the lexical file handle ('$fileIn') goes out of scope and is closed if it hasn't been closed already.

    True laziness is hard work

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://902128]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (9)
As of 2014-12-26 20:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (175 votes), past polls