How to open a file on mac OSX 10.8.2 in python

心已入冬 提交于 2020-01-11 14:42:38

问题


I am writing a python code on eclipse and want to open a file that is present in Downloads folder. I am using MAC OSX 10.8.2. I tried with f=os.path.expanduser("~/Downloads/DeletingDocs.txt") and also with

ss=subprocess.Popen("~/Downloads/DeletingDocs.txt",shell=True)
ss.communicate()

I basically want to open a file in subprocess, to listen to the changes in the opened file.But, the file is not opening in either case.


回答1:


from os.path import baspath, expanduser
filepath = abspath(expanduser("~/") + '/Downloads/DeletingDocs.txt')
print('Opening file', filepath)
with open(filepath, 'r') as fh:
    print(fh.read())

Take note of OSX file-handling tho, the IO is a bit different depending on the filetype. For instance, a .txt file which under Windows would be considered a "plain text-file" is actually a compressed data-stream under OSX because OSX tries to be "smart" about the storage space.

This can literately ruin your day unless you know about it (been there, had the headache.. moved on)

When double-clicking on a .txt file in OSX for instance normally the text-editor pops up and what it does is call for a os.open() instead of accessing it on a lower level which lets OSX middle layers do disk-area|decompression pipe|file-handle -> Texteditor but if you access the file-object on a lower level you'll end up opening the disk-area where the file is stored and if you print the data you'll get garbage because it's not the data you'd expect.

So try using:

import os
fd = os.open( "foo.txt", os.O_RDONLY )
print(os.read(fd, 1024))
os.close( fd )

And fiddle around with the flags. I honestly can't remember which of the two opens the file as-is from disk (open() or os.open()) but one of them makes your data look like garbage and sometimes you just get the pointer to the decompression pipe (giving you like 4 bytes of data even tho the text-file is hughe).

If it's tracking/catching updates on a file you want

from time import ctime
from os.path import getmtime, expanduser, abspath
from os import walk

for root, dirs, files in walk(expanduser('~/')):
    for fname in files:
        modtime = ctime(getmtime(abspath(root + '/' + fname)))
        print('File',fname,'was last modified at',modtime)

And if the time differs from your last check, well then do something cool with it. For instance, you have these libraries for Python to work with:

  • .csv
  • .pdf
  • .odf
  • .xlsx

And MANY more, so instead of opening an external application as your first fix, try opening them via Python and modify to your liking instead, and only as a last resort (if even then) open external applications via Popen.

But since you requested it (sort of... erm), here's a Popen approach:

from subprocess import Popen, PIPE, STDOUT
from os.path import abspath, expanduser
from time import sleep

run = Popen('open -t ' + abspath(expanduser('~/') + '/example.txt'), shell=True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)

##== Here's an example where you could interact with the process:
##== run.stdin.write('Hey you!\n')
##== run.stdin.flush()

while run.poll() == None:
    sleep(1)

Over-explaining your job:

This will print a files contents every time it's changed.

with open('test.txt', 'r') as fh:
    import time
    while 1:
            new_data = fh.read()
            if len(new_data) > 0:
                fh.seek(0)
                print(fh.read())
            time.sleep(5)

How it works: The regular file opener with open() as fh will open up the file and place it as a handle in fh, once you call .read() without any parameters it will fetch the entire contents of the file. This in turn doesn't close the file, it simply places the "reading" pointer at the back of the file (lets say at position 50 for convenience).

So now your pointer is at character 50 in your file, at the end. Wherever you write something in your file, that will put more data into it so the next .read() will fetch data from position 50+ making the .read() not empty, so we place the "reading" pointer back to position 0 by issuing .seek(0) and then we print all the data.

Combine that with os.path.getmtime() to fine any reversed changes or 1:1 ratio changes (replacing a character mis-spelling etc).




回答2:


I am hesitant to answer because this question was double-posted and is confusingly phrased, but... if you want to "open" the file in OSX using the default editor, then add the open command to your subprocess. This works for me:

subprocess.Popen("open myfile.txt",shell=True)



回答3:


It is most likely a permissions issue, if you try your code in the Python interpreter you will probably receive a "Permission denied" error from the shell when you call subprocess.Popen. If this is the case then you will need to make the file a minimum of 700 (it's probably 644 by default) and you'll probably want 744.

Try the code in the Python interpreter and check for the "Permission denied" error, if you see that then do this in a shell:

chmod 744 ~/Downloads/DeletingDocs.txt

Then run the script. To do it all in Python you can use os.system:

import os
import subprocess

filename = "~/Downloads/DeletingDocs.txt"
os.system("chmod 744 "+filename)
ss=subprocess.Popen(filename, shell=True)
ss.communicate()

The reason it "just works" in Windows is because Windows doesn't support file permission types (read, write and execute) in the same way as *nix systems (e.g. Linux, BSD, OS X, etc.) do.



来源:https://stackoverflow.com/questions/19273210/how-to-open-a-file-on-mac-osx-10-8-2-in-python

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