How to check whether file is open or not

Discussion in 'Python' started by Ros, Mar 7, 2007.

  1. Ros

    Ros Guest

    There are 10 files in the folder. I wish to process all the files one
    by one. But if the files are open or some processing is going on them
    then I do not want to disturb that process. In that case I would
    ignore processing that particular file and move to next file.

    How can I check whether the file is open or not?

    I tried os.stat and os.access but I am not getting the expected
    results.
    Also I checked in IO exceptions, IO error handler doesnt raise any
    error if the file is open.
    There are some options to check but they are platform dependent (works
    only with unix)

    Your help would be highly appreciated.

    Thanks,
    Ros
     
    Ros, Mar 7, 2007
    #1
    1. Advertisements

  2. You can't do that, at least not in a platform agnostic way, and usually not
    without cooperation of the file-modifying processes.

    Diez
     
    Diez B. Roggisch, Mar 7, 2007
    #2
    1. Advertisements

  3. This works only on Windows:
    You can use the _sopen function (from the C runtime library), which takes
    additional flags for specifying file sharing. See
    http://msdn2.microsoft.com/en-us/library/aa273350(VS.60).aspx
    _sopen with _SH_DENYRW will fail if the file is already open by the same
    or another process. Try to open the file using this flag: if _sopen
    succeeds (does not return -1) the file was not already open (remember to
    close it as soon as possible!); if _sopen fails (returns -1) it was
    already open.

    Using the ctypes module (included with Python 2.5; you can download and
    install it for previous versions) you can call that function easily:

    py> from ctypes import *
    py> crt = cdll.msvcrt
    py> _sopen = crt._sopen
    py> _sopen.argtypes = (c_char_p, c_int, c_int, c_int)
    py> _SH_DENYRW = 0x10 # from <share.h>
    py> h = _sopen("C:\\1.txt", 0, _SH_DENYRW, 0)
    py> h
    3
    py> h2 = _sopen("C:\\1.txt", 0, _SH_DENYRW, 0)
    py> h2
    -1
    py> _close = crt._close
    py> _close(h)
    0
    py> h2 = _sopen("C:\\1.txt", 0, _SH_DENYRW, 0)
    py> h2
    3
    py> _close(h2)
    0

    Note: You said "But if the files are open or some processing is going on
    them then I do not want to disturb that process.". There exist a (small)
    risk of disturbing the other process: if it tries to open the file just
    after you opened it, but before you close it, the operation will fail. It
    is a tiny window, but might happen...

    Surely there are other ways - some programs can report all processes
    having a certain file opened, by example, but I don't know how to do that.
     
    Gabriel Genellina, Mar 7, 2007
    #3
  4. <snip>

    From what I know: You can't, in a platform independent way.

    You'd still be in trouble even if python would let you write something like:

    if file_is_open(filename):
    process_file(filename)


    There's nothing that says no one will open the file after the
    file_is_open call but before the process_file call. Also, the file might
    be opened during the processing.

    If the files to be processed only are written and then closed without
    being reopened or modified, then your situation is a bit simpler.

    If you can get the process that creates the files to cooperate, a common
    way to solve this problem is to have a temporary suffix on files while
    they are being created. Once the file is complete, the temporary suffix
    is removed and that signals to other processes that this file is ready
    for processing.
     
    Mattias Nilsson, Mar 7, 2007
    #4
  5. Ros

    Ros Guest

    Thanks a lot Gabriel.
    ctypes is working!

    Regards,
    Ros
     
    Ros, Mar 8, 2007
    #5
  6. If you can os.open() with O_EXLOCK flag, it's not open by other
    process. Now that should work on Unix, Linux and MacOS X. All Windows
    proceeding form NT line, are supposed to be POSIX compatible, but
    somehow this flag is not available.
     
    Bart Ogryczak, Mar 8, 2007
    #6
  7. O_EXLOCK is not in POSIX.
     
    Gabriel Genellina, Mar 9, 2007
    #7
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.