11

Please look at the following code:

for i in xrange(1,5000):
    with open(r'test\test%s.txt' % i, 'w') as qq:
        qq.write('aa'*3000)

It seems to be written according to all Python rules; files are closing after using. Seems to. But in fact it seems to recommend(!) system to close file, not to close it explicitly because when I'm looking on Resource monitor it shows a lot of open files . It gives me a lot of problems because in my script I use a lot of files and after a long time I got "Too many open files" error despite of 'closing' it from source code.

Is there some way to explicitly close file in Python? Or how can I check whether the file was really(!) closed or not?

Update: I've just tried with another monitoring tool - Handle from Sysinternals and it shows all correct and I trust it. So, it may be problem in Resource monitor itself.

Screenshot which shows files opened:

Resource Monitor with the script running

8
  • 5
    I cannot reproduce this. Please could you include an SSCCE (sscce.org) that exhibits this behaviour (the code you are showing right now is at odds with the screenshot), and let us know your exact Python version and details of your OS.
    – NPE
    Commented Aug 7, 2014 at 7:12
  • Do you want to say it's the only way? I mean, I don't want to keep all this files open, I need only one file in time but Python don't close it after my request, seems they still remain opened. I know I can increase OS limit for number of opened files, but it isn't a good solution, I think. Commented Aug 7, 2014 at 7:17
  • Python 2.7, Windows 7 64-bit OS. The only difference is the file names. Commented Aug 7, 2014 at 7:18
  • Does running your above test script give you the "Too many open files" error?
    – Blender
    Commented Aug 7, 2014 at 7:38
  • 1
    I cannot reproduce this issue. Windows 7 64 bit, Python 2.7.5 - using your exact code. I do notice that you are running multiple copies of the same program (in the background screenshot); this will lead to a race condition with the file handlers and could be a cause of this. Commented Aug 7, 2014 at 8:15

2 Answers 2

11

Your code

for i in xrange(1, 5000):
    with open(r'test\test%s.txt' % i, 'w') as qq:
        qq.write('aa' * 3000)

is semantically exactly equivalent to

for i in xrange(1, 5000):
    qq = open(r'test\test%s.txt' % i, 'w')
    try:
        qq.write('aa' * 3000)
    finally:
        qq.close()

as using with with files is a way to ensure that the file is closed immediately after the with block is left.

So your problem must be somewhere else.

Maybe the version of the Python environment in use has a bug where fclose() isn't called due to some reason.

But you might try something like

try:
    qq.write('aa' * 3000)
finally:
    # qq.close()
    os.close(qq.fileno())

which does the system call directly.

3
  • I know but the problem is still here. I call 'close' but file was not closed in fact (Handler is still in system, that's what Resource Monitor shows) Commented Aug 7, 2014 at 7:34
  • @TheGodfather I have added to my answer so that might help you.
    – glglgl
    Commented Aug 7, 2014 at 7:48
  • 4
    at Python level, it is closed. Finito. If it is still open at system level, problem might be in: 1) Python implementation you are using, 2) operating system and its kerneL, 3) tool you are using to monitor opened files.
    – m.wasowski
    Commented Aug 7, 2014 at 7:57
-3

You should be able explicitly close the file by calling qq.close(). Also, python does not close a file right when it is done with it, similar to how it handles its garbage collection. You may need to look into how to get python to release all of its unused file descriptors. If it is similar to how it handles unused variable then it will tell the os that it is still using them, whether or not they are currently in use by your program.

7
  • 1
    for i in xrange(1,5000): try: qq = open(r'test\scr%s.png' % i, 'w') qq.write('aa'*3000) finally: qq.close() With this code the problem is still in place. >Also, python does not close a file right when it is done with it, That's exactly what I'm asking for. How to close file explicitly, right after using. Commented Aug 7, 2014 at 7:25
  • David, you saw the with statements, didn't you? What you wrote about releasing the file descriptors only holds without the with stuff or explicitly closing.
    – glglgl
    Commented Aug 7, 2014 at 7:27
  • @glglgl yeah, I did. Sorry, it's late here. I do think that it is similar to how it handles garbage collection. I recently ran into a problem when a python program I was making would run out of memory. It turns out that when I was done with a variable and deleted it python didn't actually release the variable. It turns out that it only runs garbage collection every 700th object created. This meant that I had to force it run garbage collection. It might be a similar issue since you aren't explicitly closing the file.
    – David
    Commented Aug 7, 2014 at 7:29
  • @David with does explicitly close the file!
    – glglgl
    Commented Aug 7, 2014 at 7:30
  • 1
    @glglgl yes, I believe 'with' explicitly calls f.close() but it seems to do not close file handler in fact. Commented Aug 7, 2014 at 7:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.