Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my file getting closed if I don't do anything with it for a while?

Original situation:

The application I'm working on at the moment will receive notification from another application when a particular file has had data added and is ready to be read. At the moment I have something like this:

class Foo(object):
    def __init__(self):
        self.myFile = open("data.txt", "r")
        self.myFile.seek(0, 2) #seeks to the end of the file

        self.mainWindow = JFrame("Foo",
                                 defaultCloseOperation = JFrame.EXIT_ON_CLOSE,
                                 size = (640, 480))
        self.btn = JButton("Check the file", actionPerformed=self.CheckFile)
        self.mainWindow.add(self.btn)
        self.mainWindow.visible = True

    def CheckFile(self, event):
        while True:
            line = self.myFile.readline()
            if not line:
                break
            print line

foo = Foo()

Eventually, CheckFile() will be triggered when a certain message is received on a socket. At the moment, I'm triggering it from a JButton.

Despite the fact that the file is not touched anywhere else in the program, and I'm not using with on the file, I keep on getting ValueError: I/O operation on closed file when I try to readline() it.

Initial Solution:

In trying to figure out when exactly the file was being closed, I changed my application code to:

foo = Foo()
while True:
    if foo.myFile.closed == True:
        print "File is closed!"

But then the problem went away! Or if I change it to:

foo = Foo()
foo.CheckFile()

then the initial CheckFile(), happening straight away, works. But then when I click the button ~5 seconds later, the exception is raised again!

After changing the infinite loop to just pass, and discovering that everything was still working, my conclusion was that initially, with nothing left to do after instantiating a Foo, the application code was ending, foo was going out of scope, and thus foo.myFile was going out of scope and the file was being closed. Despite this, swing was keeping the window open, which was then causing errors when I tried to operate on an unopened file.

Why I'm still confused:

The odd part is, if foo had gone out of scope, why then, was swing still able to hook into foo.CheckFile() at all? When I click on the JButton, shouldn't the error be that the object or method no longer exists, rather than the method being called successfully and giving an error on the file operation?

My next idea was that maybe, when the JButton attempted to call foo.CheckFile() and found that foo no longer existed, it created a new Foo, somehow skipped its __init__ and went straight to its CheckFile(). However, this doesn't seem to be the case either. If I modify Foo.__init__ to take a parameter, store that in self.myNum, and print it out in CheckFile(), the value I pass in when I instantiate the initial object is always there. This would seem to suggest that foo isn't going out of scope at all, which puts me right back where I started!!!

EDIT: Tidied question up with relevant info from comments, and deleted a lot of said comments.

like image 414
Cam Jackson Avatar asked Aug 09 '11 05:08

Cam Jackson


1 Answers

* Initial, Partial Answer (Added to Question) *

I think I just figured this out. After foo = Foo(), with no code left to keep the module busy, it would appear that the object ceases to exist, despite the fact that the application is still running, with a Swing window doing stuff.

If I do this:

foo = Foo()
while True:
    pass

Then everything works as I would expect.

I'm still confused though, as to how foo.CheckFile() was being called at all. If the problem was that foo.myFile was going out of scope and being closed, then how come foo.CheckFile() was able to be called by the JButton?

Maybe someone else can provide a better answer.

like image 155
Cam Jackson Avatar answered Oct 15 '22 15:10

Cam Jackson