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

帅比萌擦擦* 提交于 2019-12-08 23:20:37

问题


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.


回答1:


* 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.




回答2:


I think the problem arises from memory being partitioned into two types in Java, heap and non-heap.Your class instance foo gets stored in heap memory while its method CheckFile is loaded into the method area of non-heap memory. After your script finishes, there are no more references to foo so it gets marked for garbage collection, while the Swing interface is still referring to CheckFile, so it gets marked as in-use. I am assuming that foo.myFile is not considered static so it also is stored in heap memory. As for the Swing interface, it's presumably still being tracked as in-use as long as the window is open and being updated by the window manager.


Edit: your solution of using a while True loop is a correct one, in my opinion. Use it to monitor for events and when the window closes or the last line is read, exit the loop and let the program finish.


Edit 2: alternative solution - try having foo inherit from JFrame to make Swing keep a persistent pointer to it in its main loop as long as the window is open.



来源:https://stackoverflow.com/questions/6991878/why-is-my-file-getting-closed-if-i-dont-do-anything-with-it-for-a-while

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!