check if a file is open in Python
Asked Answered
I

9

76

In my app, I write to an excel file. After writing, the user is able to view the file by opening it. But if the user forgets to close the file before any further writing, a warning message should appear. So I need a way to check this file is open before the writing process. Could you supply me with some python code to do this task?

Ileum answered 26/7, 2011 at 6:10 Comment(0)
P
58

I assume that you're writing to the file, then closing it (so the user can open it in Excel), and then, before re-opening it for append/write operations, you want to check that the file isn't still open in Excel?

This is how you could do that:

while True:   # repeat until the try statement succeeds
    try:
        myfile = open("myfile.csv", "r+") # or "a+", whatever you need
        break                             # exit the loop
    except IOError:
        input("Could not open file! Please close Excel. Press Enter to retry.")
        # restart the loop

with myfile:
    do_stuff()
Pure answered 26/7, 2011 at 6:23 Comment(8)
It doesn't work. I can still open a file which is opend with 'w+' by another process.Centrifugate
@Ace: Are you talking about Excel? This question is about Excel and how it affects file locking.Pure
This is Windows specific, the question being about Excel then it makes sense, but not in every scenario this will be true. For example, if a volume is mounted in the network, you can't know if the file is open if you try this in another computer on the network, in particular UNIX or Linux servers or clients.Therm
the try statement is being ignored on my endHeth
@twinaholic: Probably not, but the program would continue running even if the file couldn't be opened. I have improved my code, thanks for your input!Pure
Is it recommended to close the file myfile.close() at the end of program?Machiavelli
@alper: The with statement does that automatically.Pure
@TimPietzcker Yes but if I use print wrapper function that writes into same file as a daemon process, should I keep the file open until the daemon process is ended, that is opened on the program startup. Something like console = Console(file=open(filename, "a"), force_terminal=True) while using rich.Machiavelli
O
70

If all you care about is the current process, an easy way is to use the file object attribute "closed"

f = open('file.py')
if f.closed:
  print 'file is closed'

This will not detect if the file is open by other processes!

source: http://docs.python.org/2.4/lib/bltin-file-objects.html

Orjonikidze answered 20/9, 2013 at 20:4 Comment(5)
The .closed attribute checks if file is closed by current Python process. It does not check if file is open or closed by any another process.Mudslinger
@Rmhero: Please consider deleting your answer, because it is incorrect, thus can lead people to write code that behaves differently than intended. It works as @Mudslinger describes. To see this, just open two ipython shells, then f = open('foo.txt', 'w') in one, but f = open('foo.txt', 'r') in the other. Then f.closed is False, but f.close() in the second terminal suffices to turn this into f.closed is True.Cryometer
@Ioannis Filippidis - If he hadn't given his answer, you wouldn't have been able to deliver your message. Much rather have his message and yours than neither.Tannenberg
This is posted as an answer, which it is not. Amending it to be an answer, with a comment about what to avoid would make sense.Cryometer
This is exactly what I needed, and works as intended if you are doing a file operation, e.g scraping from the web then writing to a file and want to know when it's completed to either carry on operations or to display 'done' to the user. Its a valuable answer.Delldella
P
58

I assume that you're writing to the file, then closing it (so the user can open it in Excel), and then, before re-opening it for append/write operations, you want to check that the file isn't still open in Excel?

This is how you could do that:

while True:   # repeat until the try statement succeeds
    try:
        myfile = open("myfile.csv", "r+") # or "a+", whatever you need
        break                             # exit the loop
    except IOError:
        input("Could not open file! Please close Excel. Press Enter to retry.")
        # restart the loop

with myfile:
    do_stuff()
Pure answered 26/7, 2011 at 6:23 Comment(8)
It doesn't work. I can still open a file which is opend with 'w+' by another process.Centrifugate
@Ace: Are you talking about Excel? This question is about Excel and how it affects file locking.Pure
This is Windows specific, the question being about Excel then it makes sense, but not in every scenario this will be true. For example, if a volume is mounted in the network, you can't know if the file is open if you try this in another computer on the network, in particular UNIX or Linux servers or clients.Therm
the try statement is being ignored on my endHeth
@twinaholic: Probably not, but the program would continue running even if the file couldn't be opened. I have improved my code, thanks for your input!Pure
Is it recommended to close the file myfile.close() at the end of program?Machiavelli
@alper: The with statement does that automatically.Pure
@TimPietzcker Yes but if I use print wrapper function that writes into same file as a daemon process, should I keep the file open until the daemon process is ended, that is opened on the program startup. Something like console = Console(file=open(filename, "a"), force_terminal=True) while using rich.Machiavelli
D
8

For windows only

None of the other provided examples would work for me when dealing with this specific issue with excel on windows 10. The only other option I could think of was to try and rename the file or directory containing the file temporarily, then rename it back.

import os

try: 
    os.rename('file.xls', 'tempfile.xls')
    os.rename('tempfile.xls', 'file.xls')
except OSError:
    print('File is still open.')
Disturbance answered 8/2, 2017 at 19:54 Comment(2)
This is not a bad solution if you have few users for the file...it is indeed a sort of locking mechanism on a private file.Konstanze
Be aware that this is very Windows specific as most other OSes will happily rename files if they're already open.Daniels
F
5

You could use with open("path") as file: so that it automatically closes, else if it's open in another process you can maybe try as in Tims example you should use except IOError to not ignore any other problem with your code :)

try:
   with open("path", "r") as file: # or just open
       # Code here
except IOError:
   # raise error or print
Freehanded answered 26/7, 2011 at 6:22 Comment(1)
Never do an except without specifying the exception you want to catch. Also, the scope of your try block is too broad - Shansal wants to check whether the file can be opened at all. Error handling while writing to the file (or whatever else happens in the with block) should be separate.Pure
M
3

Try this method if the above methods corrupt your excel file.

This function attempts to rename the file with its own name. If the file has already been opened, the edit will be reject by the os and an OSError exception will be raised. It does not touch the inner code so it will not corrupt your excel files. LMK if it worked for you.

def check_file_status(self):
try:
    os.rename("file1.xlsx", "file1.xlsx")
    print("File is closed.")
except OSError:
    print("File is opened.")
Mortise answered 10/5, 2022 at 10:3 Comment(0)
W
2

Using

try:
with open("path", "r") as file:#or just open

may cause some troubles when file is opened by some other processes (i.e. user opened it manually). You can solve your poblem using win32com library. Below code checks if any excel files are opened and if none of them matches the name of your particular one, openes a new one.

import win32com.client as win32
xl = win32.gencache.EnsureDispatch('Excel.Application')

my_workbook = "wb_name.xls"
xlPath="my_wb_path//" + my_workbook


if xl.Workbooks.Count > 0:
    # if none of opened workbooks matches the name, openes my_workbook 
    if not any(i.Name == my_workbook for i in xl.Workbooks): 
        xl.Workbooks.Open(Filename=xlPath)
        xl.Visible = True
#no workbooks found, opening
else:  
    xl.Workbooks.Open(Filename=xlPath)
    xl.Visible = True

'xl.Visible = True is not necessary, used just for convenience'

Hope this will help

Whoreson answered 27/6, 2019 at 9:28 Comment(0)
T
-1

For .xlsx files on Windows, a temporary file exists while the file is in open state. This file is named ~$filename.xlsx when the original file is named filename.xlsx.

If this file is still present, this means that the file is still open:

my_file = "file.xlsx"
temp_file = "~$" + my_file
while temp_path.is_file():
    # file is still open
    pass
print('file is closed')
Trotskyism answered 3/7 at 13:6 Comment(0)
D
-2
if myfile.closed == False:
   print("File is still open ################")
Diver answered 24/2, 2021 at 5:31 Comment(1)
It is basically a copy of this existing answer that uses the .closed attribute.Nodarse
G
-3

Just use this function. It will close any already opened excel file

import os

def close():

    try:
        os.system('TASKKILL /F /IM excel.exe')

    except Exception:
        print("KU")

close()
Guitarfish answered 24/5, 2021 at 16:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.