File locking is impossible in Windows?

Discussion in 'Python' started by Pekka Niiranen, Dec 21, 2004.

  1. Hi,

    I have used the following example from win32 extensions:

    -----SCRIPT STARTS----

    import win32file
    import win32con
    import win32security
    import pywintypes

    class Flock:
    def __init__(self,file):
    self.file=file
    secur_att = win32security.SECURITY_ATTRIBUTES()
    secur_att.Initialize()
    self.highbits=-0x7fff0000
    self.hfile=win32file.CreateFile( self.file,\
    win32con.GENERIC_READ|win32con.GENERIC_WRITE,\
    win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,\
    secur_att, win32con.OPEN_ALWAYS,\
    win32con.FILE_ATTRIBUTE_NORMAL , 0 )
    def lock(self):
    lock_flags=win32con.LOCKFILE_EXCLUSIVE_LOCK|\
    win32con.LOCKFILE_FAIL_IMMEDIATELY
    self.ov=pywintypes.OVERLAPPED()
    win32file.LockFileEx(self.hfile,lock_flags,0,\
    self.highbits,self.ov)
    def unlock(self):
    win32file.UnlockFileEx(self.hfile,0,\
    self.highbits,self.ov)
    self.hfile.Close()

    if __name__ == '__main__':
    from time import time, strftime, localtime
    import sys

    l=Flock("e:\\\\log.txt")
    print 'calling lock'
    l.lock()
    print "Now locked. Hit enter to release lock."
    dummy = sys.stdin.readline()

    l.unlock()
    print 'now unlocked'

    -----SCRIPT ENDS----

    If I start one python process from dos window I get message:

    E:\>python lockker.py
    calling lock
    Now locked. Hit enter to release lock.

    All well, now if

    1) I start another Dos -shell and run the same command I get:

    E:\>python lockker.py
    calling lock
    Traceback (most recent call last):
    File "lockker.py", line 35, in ?
    l.lock()
    File "lockker.py", line 23, in lock
    win32file.LockFileEx(self.hfile,lock_flags,0,\
    self.highbits,self.ov)
    pywintypes.error: (33, 'LockFileEx',\
    'The process cannot access the file because\
    another process has locked a portion of the file.')

    Which is correct.

    2) I try to read the contents of the file from Dos -shell, I get:
    E:\>type log.txt
    The process cannot access the file because another\
    process has locked a portion of the file.

    This is correct.

    3) When I open the file into notepad.exe I can edit the screen
    but not write changes to disk. Correct again!

    4) I cannot delete the file from Dos shell or from W2K explorer
    which is correct.

    5) However, I can overwrite the file over with:
    E:\>copy d:\log.txt log.txt
    1 file(s) copied.

    Which is WRONG as is me being able to copy another file over it
    with W2K explorer too.


    Is there a way around this? How can I stop file being COPIED OVER while
    it is being open? Is this window's feature? Is readlines() operation
    "atomic" enough for me not to worry about these issues?

    My python script modifies set of files from a directory one by one.
    I try to lock them all exclusively for the script
    until all are modified. If one of the files gets overwritten
    by another version (by another process) the script may fail.

    -pekka-
    Pekka Niiranen, Dec 21, 2004
    #1
    1. Advertising

  2. Pekka Niiranen wrote:

    > Is there a way around this? How can I stop file being COPIED OVER while
    > it is being open?


    you could rename the file before you start updating it, and rename it back when
    done.

    </F>
    Fredrik Lundh, Dec 21, 2004
    #2
    1. Advertising

  3. Pekka Niiranen

    Roger Upole Guest

    I get

    The process cannot access the file because another process has locked a
    portion of the file.
    0 file(s) copied.

    on both Win2k and WinXP. (Python 2.4, Pywin32 build 203)
    Are you sure the log.txt you're copying to is actually the right one ? You
    should at least get a
    prompt to confirm overwrite on the command line.

    Roger



    "Pekka Niiranen" <> wrote in message
    news:41c899ba$0$15097$...
    > Hi,
    >
    > I have used the following example from win32 extensions:
    >
    > -----SCRIPT STARTS----
    >
    > import win32file
    > import win32con
    > import win32security
    > import pywintypes
    >
    > class Flock:
    > def __init__(self,file):
    > self.file=file
    > secur_att = win32security.SECURITY_ATTRIBUTES()
    > secur_att.Initialize()
    > self.highbits=-0x7fff0000
    > self.hfile=win32file.CreateFile( self.file,\
    > win32con.GENERIC_READ|win32con.GENERIC_WRITE,\
    > win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,\
    > secur_att, win32con.OPEN_ALWAYS,\
    > win32con.FILE_ATTRIBUTE_NORMAL , 0 )
    > def lock(self):
    > lock_flags=win32con.LOCKFILE_EXCLUSIVE_LOCK|\
    > win32con.LOCKFILE_FAIL_IMMEDIATELY
    > self.ov=pywintypes.OVERLAPPED()
    > win32file.LockFileEx(self.hfile,lock_flags,0,\
    > self.highbits,self.ov)
    > def unlock(self):
    > win32file.UnlockFileEx(self.hfile,0,\
    > self.highbits,self.ov)
    > self.hfile.Close()
    >
    > if __name__ == '__main__':
    > from time import time, strftime, localtime
    > import sys
    >
    > l=Flock("e:\\\\log.txt")
    > print 'calling lock'
    > l.lock()
    > print "Now locked. Hit enter to release lock."
    > dummy = sys.stdin.readline()
    >
    > l.unlock()
    > print 'now unlocked'
    >
    > -----SCRIPT ENDS----
    >
    > If I start one python process from dos window I get message:
    >
    > E:\>python lockker.py
    > calling lock
    > Now locked. Hit enter to release lock.
    >
    > All well, now if
    >
    > 1) I start another Dos -shell and run the same command I get:
    >
    > E:\>python lockker.py
    > calling lock
    > Traceback (most recent call last):
    > File "lockker.py", line 35, in ?
    > l.lock()
    > File "lockker.py", line 23, in lock
    > win32file.LockFileEx(self.hfile,lock_flags,0,\
    > self.highbits,self.ov)
    > pywintypes.error: (33, 'LockFileEx',\
    > 'The process cannot access the file because\
    > another process has locked a portion of the file.')
    >
    > Which is correct.
    >
    > 2) I try to read the contents of the file from Dos -shell, I get:
    > E:\>type log.txt
    > The process cannot access the file because another\
    > process has locked a portion of the file.
    >
    > This is correct.
    >
    > 3) When I open the file into notepad.exe I can edit the screen
    > but not write changes to disk. Correct again!
    >
    > 4) I cannot delete the file from Dos shell or from W2K explorer
    > which is correct.
    >
    > 5) However, I can overwrite the file over with:
    > E:\>copy d:\log.txt log.txt
    > 1 file(s) copied.
    >
    > Which is WRONG as is me being able to copy another file over it
    > with W2K explorer too.
    >
    >
    > Is there a way around this? How can I stop file being COPIED OVER while
    > it is being open? Is this window's feature? Is readlines() operation
    > "atomic" enough for me not to worry about these issues?
    >
    > My python script modifies set of files from a directory one by one.
    > I try to lock them all exclusively for the script
    > until all are modified. If one of the files gets overwritten
    > by another version (by another process) the script may fail.
    >
    > -pekka-
    >
    >
    >
    >
    >
    >
    >





    -----------== Posted via Newsfeed.Com - Uncensored Usenet News ==----------
    http://www.newsfeed.com The #1 Newsgroup Service in the World!
    -----= Over 100,000 Newsgroups - Unlimited Fast Downloads - 19 Servers =-----
    Roger Upole, Dec 22, 2004
    #3
  4. Pekka Niiranen

    Guest

    I just have written the program in "C", which does the same. It behaves
    almost the way you described.

    Tthe copy command gives such diagnostic:

    The process cannot access the file because
    another process has locked a portion of the file.
    0 file(s) copied.

    BUT THE FILE IS ACTUALLY OVERWRITTEN..

    I'm posting this question on MS newsgroup
    microsoft.public.win32.programmer.kernel
    , Dec 22, 2004
    #4
  5. Re: File locking is impossible in Windows? SOLUTION

    Hi everybody:

    I played with the class Flock and changed the line
    win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,\
    to
    win32con.FILE_SHARE_READ,\
    and now I cannot copy the file over which suits me.

    When file is NOT locked I get:
    E:\>copy d:\log.txt .
    Overwrite .\log.txt? (Yes/No/All): y
    1 file(s) copied.

    When file IS locked I get:

    E:\>copy d:\log.txt .
    The process cannot access the file because it is being used by another
    process.
    0 file(s) copied.

    Below is the new script completely. Note that when
    upgrading to Python v2.4 I had to change self.highbits
    from 0xffff0000 to -0x7fff0000.

    -----SCRIPT STARTS----

    import win32file
    import win32con
    import win32security
    import pywintypes

    class Flock:
    def __init__(self,file):
    self.file=file
    secur_att = win32security.SECURITY_ATTRIBUTES()
    secur_att.Initialize()
    self.highbits=-0x7fff0000
    self.hfile=win32file.CreateFile( self.file,\
    win32con.GENERIC_READ|win32con.GENERIC_WRITE,\
    win32con.FILE_SHARE_READ,\ secur_att,\
    win32con.OPEN_ALWAYS,\
    win32con.FILE_ATTRIBUTE_NORMAL , 0)

    def lock(self):
    lock_flags=win32con.LOCKFILE_EXCLUSIVE_LOCK|\
    win32con.LOCKFILE_FAIL_IMMEDIATELY
    self.ov=pywintypes.OVERLAPPED()
    win32file.LockFileEx(self.hfile,lock_flags,0,\
    self.highbits,self.ov)

    def unlock(self):
    win32file.UnlockFileEx(self.hfile,0,\
    self.highbits,self.ov)
    self.hfile.Close()

    if __name__ == '__main__':
    import sys
    l=Flock("e:\\\\log.txt")
    print 'calling lock'
    l.lock()
    print "Now locked. Hit enter to release lock."
    dummy = sys.stdin.readline()

    l.unlock()
    print 'now unlocked'

    -----SCRIPT ENDS----

    -pekka-


    Pekka Niiranen wrote:
    > Hi,
    >
    > I have used the following example from win32 extensions:
    >
    > -----SCRIPT STARTS----
    >
    > import win32file
    > import win32con
    > import win32security
    > import pywintypes
    >
    > class Flock:
    > def __init__(self,file):
    > self.file=file
    > secur_att = win32security.SECURITY_ATTRIBUTES()
    > secur_att.Initialize()
    > self.highbits=-0x7fff0000
    > self.hfile=win32file.CreateFile( self.file,\
    > win32con.GENERIC_READ|win32con.GENERIC_WRITE,\
    > win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,\
    > secur_att, win32con.OPEN_ALWAYS,\
    > win32con.FILE_ATTRIBUTE_NORMAL , 0 )
    > def lock(self):
    > lock_flags=win32con.LOCKFILE_EXCLUSIVE_LOCK|\
    > win32con.LOCKFILE_FAIL_IMMEDIATELY
    > self.ov=pywintypes.OVERLAPPED()
    > win32file.LockFileEx(self.hfile,lock_flags,0,\
    > self.highbits,self.ov)
    > def unlock(self):
    > win32file.UnlockFileEx(self.hfile,0,\
    > self.highbits,self.ov)
    > self.hfile.Close()
    >
    > if __name__ == '__main__':
    > from time import time, strftime, localtime
    > import sys
    >
    > l=Flock("e:\\\\log.txt")
    > print 'calling lock'
    > l.lock()
    > print "Now locked. Hit enter to release lock."
    > dummy = sys.stdin.readline()
    >
    > l.unlock()
    > print 'now unlocked'
    >
    > -----SCRIPT ENDS----
    >
    > If I start one python process from dos window I get message:
    >
    > E:\>python lockker.py
    > calling lock
    > Now locked. Hit enter to release lock.
    >
    > All well, now if
    >
    > 1) I start another Dos -shell and run the same command I get:
    >
    > E:\>python lockker.py
    > calling lock
    > Traceback (most recent call last):
    > File "lockker.py", line 35, in ?
    > l.lock()
    > File "lockker.py", line 23, in lock
    > win32file.LockFileEx(self.hfile,lock_flags,0,\
    > self.highbits,self.ov)
    > pywintypes.error: (33, 'LockFileEx',\
    > 'The process cannot access the file because\
    > another process has locked a portion of the file.')
    >
    > Which is correct.
    >
    > 2) I try to read the contents of the file from Dos -shell, I get:
    > E:\>type log.txt
    > The process cannot access the file because another\
    > process has locked a portion of the file.
    >
    > This is correct.
    >
    > 3) When I open the file into notepad.exe I can edit the screen
    > but not write changes to disk. Correct again!
    >
    > 4) I cannot delete the file from Dos shell or from W2K explorer
    > which is correct.
    >
    > 5) However, I can overwrite the file over with:
    > E:\>copy d:\log.txt log.txt
    > 1 file(s) copied.
    >
    > Which is WRONG as is me being able to copy another file over it
    > with W2K explorer too.
    >
    >
    > Is there a way around this? How can I stop file being COPIED OVER while
    > it is being open? Is this window's feature? Is readlines() operation
    > "atomic" enough for me not to worry about these issues?
    >
    > My python script modifies set of files from a directory one by one.
    > I try to lock them all exclusively for the script
    > until all are modified. If one of the files gets overwritten
    > by another version (by another process) the script may fail.
    >
    > -pekka-
    >
    >
    >
    >
    >
    >
    >
    Pekka Niiranen, Dec 22, 2004
    #5
  6. Pekka Niiranen

    Guest

    Re: File locking is impossible in Windows? SOLUTION

    Sure it will do if one of the processes needs read access only.

    Scenario when you need shared rw acces with locking:
    In the file you have "records" say 30 bytes long, 2 processes are
    reading/writing these records by: lock-read-unlock or lock-write-unlock
    .. Both processes have to open the file with rw access and the third
    process can overwrite the locked file. Actually the common method to
    prevent file from been overwritten is: lock the region outside the
    file. Such feacure is added to lock/unlock namely for this purpose.

    You found the bug in WIN32.

    In fact the file locked and overwritten hav ALL BYTES ZERO and the
    length of the copyed file.
    , Dec 22, 2004
    #6
  7. Pekka Niiranen

    Guest

    Re: File locking is impossible in Windows? SOLUTION

    Sure it will do if one of the processes needs read access only.

    Scenario when you need shared rw acces with locking:
    In the file you have "records" say 30 bytes long, 2 processes are
    reading/writing these records by: lock-read-unlock or lock-write-unlock
    .. Both processes have to open the file with rw access. But the third
    process can overwrite the locked file! Actually the common method to
    prevent file from been overwritten is: lock the region outside the
    file. Such feacure is added to lock/unlock namely for this purpose.

    You found the bug in WIN32.

    PS.

    When you copy the file (say c:\b) over file with locked region say
    (c:\a), the length of the file c:\b becomes the length of c:\a, and the
    content of c:\a is all zeroes. By the way, I would understand the logic
    if copy copyes bytes outside locked regions but preserves all locks.
    , Jan 3, 2005
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guy Lateur

    Locking a file under Windows

    Guy Lateur, Nov 24, 2005, in forum: Python
    Replies:
    0
    Views:
    310
    Guy Lateur
    Nov 24, 2005
  2. Tim Golden

    RE: Locking a file under Windows

    Tim Golden, Nov 24, 2005, in forum: Python
    Replies:
    2
    Views:
    313
    Guy Lateur
    Nov 24, 2005
  3. Timasmith
    Replies:
    4
    Views:
    451
    Bjorn Borud
    Nov 1, 2006
  4. Ludwigi Beethoven
    Replies:
    5
    Views:
    320
    Mike Hall
    Jul 26, 2003
  5. Replies:
    5
    Views:
    256
    Michele Dondi
    Jun 30, 2006
Loading...

Share This Page