1

I am writing a Python logger script which writes to a CSV file in the following manner:

  1. Open the file
  2. Append data
  3. Close the file (I think this is necessary to save the changes, to be safe after every logging routine.)

PROBLEM:
The file is very much accessible through Windows Explorer (I'm using XP). If the file is opened in Excel, access to it is locked by Excel. When the script tries to append data, obviously it fails, then it aborts altogether.

OBJECTIVE:
Is there a way to lock a file using Python so that any access to it remains exclusive to the script? Or perhaps my methodology is poor in the first place?

Kit
  • 30,365
  • 39
  • 105
  • 149
  • 1
    possible duplicate of [What is the best way to open a file for exclusive access in Python?](http://stackoverflow.com/questions/186202/what-is-the-best-way-to-open-a-file-for-exclusive-access-in-python) – Chris Morgan Dec 13 '10 at 11:21
  • The answers to that other question required additional modules. My chosen answer below solves the problem with built-in capabilities. – Kit Dec 15 '10 at 07:37

2 Answers2

4

Rather than closing and reopening the file after each access, just flush its buffer:

theloggingfile.flush()

This way, you keep it open for writing in Python, which should lock the file from other programs opening it for writing. I think Excel will be able to open it as read-only while it's open in Python, but I can't check that without rebooting into Windows.

EDIT: I don't think you need the step below. .flush() should send it to the operating system, and if you try to look at it in another program, the OS should give it the cached version. Use os.fsync to force the OS to really write it to the hard drive, e.g. if you're concerned about sudden power failures.

os.fsync(theloggingfile.fileno())
Thomas K
  • 39,200
  • 7
  • 84
  • 86
  • -1 because, even though what the answer says is true, it doesn't address the question that was asked. The question is about file locking rather than syncing file buffers to disk. – Bryan Oakley Dec 13 '10 at 12:51
  • @Bryan: But if he keeps it open for writing, I think that should lock it. Thereby achieving what he wants. – Thomas K Dec 13 '10 at 12:57
  • +1 He addressed the last part which says "...my methodology is poor in the first place..." – Kit Dec 13 '10 at 12:58
  • @Kit: You might want to check that it works as you expect--I'm not on Windows, so I can't test it. I think, while the file is open with Python, Excel should open it as read-only. – Thomas K Dec 13 '10 at 13:07
  • @Thomas K: I think if you put in your answer what you put in your comment (about how keeping it open effectively locks it) your answer will be a better one, and I'll not only remove the downvote, I'll add an upvote. Don't make the reader read between the lines to figure out your point. – Bryan Oakley Dec 13 '10 at 15:34
  • @Bryan: You're right, I hadn't explained how it would help. I've added the explanation to my answer. – Thomas K Dec 13 '10 at 16:12
  • Works very well. When I get to Excel, I'd get the usual "Ready Only, Notify, or Cancel" options. `os.fsync` is also necessary, according to [file.flush](http://docs.python.org/library/stdtypes.html#file.flush) in the Python docs. I think it would do well to edit your answer to indicate the necessity and recommendation for `os.fsync` – Kit Dec 15 '10 at 07:34
  • @Kit: Have you tried it without os.fsync? From what I understand, Excel should see the latest version without you having to do that, because Windows knows to give it the updated version. – Thomas K Dec 15 '10 at 10:26
0

As far as I know, Windows does not support file locking. In other words, applications that don't know about your file being locked can't be prevented from reading a file.

But the remaining question is: how can Excel accomplish this?

You might want to try to write to a temporary file first (one that Excel does not know about) and replace the original file by it lateron.

David
  • 3,787
  • 2
  • 29
  • 43