1

i am just trying to do the basic opening of the file while monitoring whether it's still opened or not, but it just opens it and exits. any suggestions to why that happens?

class Opener:
    def __init__(self, file_path):
        self.file_path = file_path
        self.process = None

    def start(self):
        sub = subprocess.Popen(self.file_path, shell=True)
        while sub.poll():
            pass
        print "closed"
new = Opener("test.jpg")
t1 = threading.Thread(target=new.start)
t1.start()
Tomer waldman
  • 23
  • 1
  • 4

3 Answers3

0

Don't use subprocess.Popen to open a file. As you can see in the documentation it is used to run child programs in a new process. But if you want to open a file for reading do

with open(self.file_path, 'r') as f:
    # do somethin here
    pass

The file will be opened at the beginning of the with statement and closed afterwards.

MrLeeh
  • 5,321
  • 6
  • 33
  • 51
  • i am trying to check whether it is closed or not, not only reading the contents. i am also trying to start it through the default program on windows so i will have to run it from the shell – Tomer waldman Jan 03 '17 at 15:26
  • Then you should have a look at http://stackoverflow.com/questions/6825994/check-if-a-file-is-open-in-python – MrLeeh Jan 03 '17 at 15:31
0

Popen is meant to create new processes (as in, execute another program from your python script), not open files. You can use the mutiprocessing module to execute the function that opens the file in a different process, instead of

t1 = threading.Thread(target=new.start)

use:

t1 = multiprocessing.Process(target=new.start)

and change function Opener.start so it opens a file and asks about it's state. Something like this:

def start(self):
    sub = open(self.file_path)
    while not sub.closed:
        pass
    print "closed"
yorodm
  • 4,359
  • 24
  • 32
0

This only works on Windows with shell=True because the default program for the extension is used to open the given file, it's the equivalent of using cmd /c Path\To\File

The problem is that

while sub.poll():
    pass

does not what you want. sub.poll() returns None while the program is running, and the exit code of the program when it has finished. If the program were to terminate with an exit code other then 0 before reaching this loop, then it would just keep looping and consuming CPU. If the program is still running or has completed successfully then the loop is not entered at all.

Checking wheather a process is still runing using poll() should be done by checking sub.poll() is None, or better use sub.wait().

Some programs however allow only one active instance, if you try to start a second instance it will instead open the file in the open window and exit immediately. In that case there is no easy way to know wheather the file is still open in the application. So the behaviour also depends on the registered program.

mata
  • 67,110
  • 10
  • 163
  • 162