简体   繁体   中英

Check for open text file

I'm writing a Python application with opens several text files in different threads. I want each thread to make some operations on the file while it is open. When the external text editor closes the file the processing of the corresponding thread should stop. So I need to check on whether the text file is still opened or not.

class MyThread (Thread):

def __init__(self, sf):
    Thread.__init__(self)
    self.sf = sf # sourcefile

def run (self):
    subprocess.Popen([EDITOR, self.sf])

The problem now is that subprocess opens the file in the editor and run() terminates. How can I keep the run() open until I close the file externally?

Did you try the subprocess.call method?

subprocess.call('notepad')

This waits for the command to complete before the process terminates and returns control back to the program.

This is what i wrote:

import subprocess from threading import Thread

class MyThread(Thread):

    def __init__(self, sf):
        Thread.__init__(self)
        self.sf = sf

    def run(self):

        subprocess.call('notepad ' + self.sf)


def main():
    myThread = MyThread('test.txt')
    myThread.start()
    while myThread.isAlive():
        print "Still Alive"


if __name__ == '__main__':
    main()

The program keeps printing "Still Alive" till I close the notepad window.

You have two events: FileOpen and FileClose. FileOpen happens when the editor is opened. FileClose is done when the editor closes? Or when the editor closes the file? If it's just on closing the editor then it should be straightforward to find out when the subprocess closes and then kill the worker threads.

Unless an editor provides a particular API, it's going to be a really nasty hack to find out if it closed the file but the editor remains open. Eg You may have to poll lsof and process the output.

It sounds similar to what a revision control system does when you commit a file and it opens an editor for you. Maybe you should check the hg or bzr code bases. Here is how mercurial handles it. And here is how bazaar handles it.

I changed Shekar's version to work with vim and use the list as a command in the subprocess.call command (and added imports) . It works as he describes.

from threading import Thread                                                    
import subprocess                                                               
class MyThread(Thread):                                                         
    def __init__(self, sf):                                                     
        Thread.__init__(self)                                                   
        self.sf = sf                                                            
    def run(self):                                                              
        subprocess.call(['/usr/bin/vim', self.sf])                              

def main():                                                                     
    myThread = MyThread('test.txt')                                             
    myThread.start()                                                            
    while myThread.isAlive():                                                   
        print "Still Alive"                                                     

if __name__ == '__main__':                                                      
    main()  

I found the problem. I was calling the editor MacVim via command line with /usr/bin/mvim. Now I changed it to /Applications/MacVim.app/Contents/MacOS/MacVim and it works as expected. I think that is because it checks the only process which it handles directly, in the first case it was the terminal and not the editor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM