【问题标题】:How to open a file on mac OSX 10.8.2 in python如何在 python 的 mac OSX 10.8.2 上打开文件
【发布时间】:2013-10-16 21:09:39
【问题描述】:

我正在 Eclipse 上编写一个 python 代码,并想打开一个存在于下载文件夹中的文件。我正在使用 MAC OSX 10.8.2。我试过f=os.path.expanduser("~/Downloads/DeletingDocs.txt") 还有

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

我基本上想在子进程中打开一个文件,以监听打开文件的变化。但是,无论哪种情况,文件都没有打开。

【问题讨论】:

  • Popen的第一个参数应该是可执行文件,而不是文本文件。
  • @cdarke ss=subprocess.Popen("~/Downloads/DeletingDocs.txt",shell=True) 在 Windows 中工作正常。但在 mac osx 中,它不起作用。
  • 在 Windows 下,我希望任何执行不可执行文件的尝试都会运行默认应用程序来打开此类文件。充其量,这是对Popen 的滥用,因为它肯定是不可移植的。

标签: python macos file subprocess popen


【解决方案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())

请注意 OSX 文件处理,IO 会因文件类型而有所不同。 例如,.txt 文件在 Windows 下将被视为“纯文本文件”实际上是 OSX 下的压缩数据流,因为 OSX 试图“智能”存储空间。

除非你知道这件事,否则这会彻底毁掉你的一天(去过那里,头疼……继续前进)

当在 OSX 中双击 .txt 文件时,通常会弹出文本编辑器,它所做的是调用 os.open() 而不是在较低级别访问它,这让 OSX 中间层可以@ 987654329@ 但如果您在较低级别访问文件对象,您最终将打开存储文件的磁盘区域,如果您打印数据,您将得到垃圾,因为它不是您期望的数据。

所以尝试使用:

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

然后摆弄旗帜。 老实说,我不记得这两个中的哪一个按原样从磁盘打开文件(open()os.open()),但其中一个让你的数据看起来像垃圾,有时你只是得到指向解压管道的指针(给即使文本文件很长,你也喜欢 4 字节的数据。

如果它正在跟踪/捕获您想要的文件的更新

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)

如果时间与您上次检查的时间不同,那就用它做一些很酷的事情。 例如,您可以使用以下 Python 库:

还有更多,因此不要将打开外部应用程序作为您的第一个修复程序,而是尝试通过 Python 打开它们并根据自己的喜好进行修改,并且仅作为最后的手段(即使那样)通过 Popen 打开外部应用程序。

但既然您提出了要求(有点……呃),这里有一个 Popen 方法

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)

过度解释你的工作:

这将在每次更改时打印文件内容。

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)

工作原理: 常规文件打开器with open() as fh 将打开文件并将其作为句柄放置在fh 中,一旦您不带任何参数调用.read(),它将获取文件的全部内容。 这反过来不会关闭文件,它只是将“读取”指针放在文件的后面(为了方便起见,我们说在位置 50)。

所以现在您的指针位于文件中的第 50 个字符处,最后。 无论您在文件中的何处写入内容,都会将更多数据放入其中,因此下一个 .read() 将从位置 50+ 获取数据,使 .read() 不为空,因此我们通过发出将“读取”指针放回位置 0 .seek(0) 然后我们打印所有数据。

将其与 os.path.getmtime() 结合使用,以微调任何反向更改或 1:1 比例更改(替换字符拼写错误等)。

【讨论】:

  • 它在控制台中打印文件内容。实际上,我想像往常一样打开一个文件,就像 textediter 一样。这样我就可以编辑文件了。
  • 它在控制台中打印文件内容。实际上,我想像往常一样打开一个文件,就像 textediter 一样。这样我就可以编辑文件了。 Acutally,我想打开不同的文件类型,如 .odt、.csv.、.pdf 和所有。
  • 您在第一个答案中没有提到这一点。其次,您应该以编程方式打开它们并跟踪更改,而不是通过子流程通道。主要原因是检查它所需的资源要少得多,而不是外部应用程序执行它。其次,Python 支持您提到的所有这些文件类型。 (见我的编辑)
  • @HarishBarvekar 检查最新的编辑顺便说一句,它显示了如何在没有任何问题的情况下采用 Popen 方式(在我尘土飞扬的旧 Mac book pro 上测试)。
  • 代码中有错字:第一行“from os.path import baspath, expanduser”,baspath应该是abspath
【解决方案2】:

这很可能是权限问题,如果您在 Python 解释器中尝试您的代码,您可能会在调用 subprocess.Popen 时从 shell 收到“权限被拒绝”错误。如果是这种情况,那么您需要使文件至少为 700(默认情况下可能为 644),并且您可能需要 744。

在 Python 解释器中尝试代码并检查“权限被拒绝”错误,如果您看到,则在 shell 中执行此操作:

chmod 744 ~/Downloads/DeletingDocs.txt

然后运行脚本。要在 Python 中完成这一切,您可以使用 os.system:

import os
import subprocess

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

它在 Windows 中“正常工作”的原因是因为 Windows 不像 *nix 系统(例如 Linux、BSD、OS X 等)那样支持文件权限类型(读、写和执行)。 .

【讨论】:

  • 是的,有“权限被拒绝”。我尝试使用您的代码,但没有成功。我想打开一个不像在控制台中打印内容的文件。我想打开任何文件类型,编辑其内容并保存。
  • 在这种情况下,您可能不想使用子进程。只需直接打开文件并对其进行操作(例如读取、写入和追加)。
  • 是的,这就是我要问的,如何打开文件。文件未打开。我想像在 Windows 中正常打开的文件一样打开文件,方法是双击它。我在 mac osx 上使用 python。
  • Python 文档 covers this 非常好,file objects 上的 Dive Into Python 部分也是如此。实际上,您可以从 Dive Into Python(一本用于学习该语言的免费书籍)中受益匪浅,尽管考虑到它的时代,它只涉及 Python 2 而不是 Python 3。不过,对于您似乎想要做的事情,这将使差别很小。
  • 非常感谢您的回复。在 windows os.popen(filename) 和 ss=subprocess.Popen(filename, shell=True) 工作正常。但是,我不明白为什么它在 mac osx 中不起作用。
【解决方案3】:

我不愿回答,因为这个问题被重复发布并且措辞令人困惑,但是......如果你想使用默认编辑器在 OSX 中“打开”文件,那么将 open 命令添加到你的子进程.这对我有用:

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

【讨论】:

  • subprocess.Popen("open myfile.txt",shell=True) 在这个文件的路径被改变了。实际上文件路径是eclipse +文件名上的python工作区。在那个位置,文件不存在。
  • 您应该将文件路径放在myfile.txt 的位置。关键部分是将open 命令添加到shell 命令中。如果您找到文件的路径,则该文件应使用默认应用程序在 GUI 中打开。但是听起来问题的描述现在是监视文件的更改,而不是打开它?我们正在尽力猜测,但也许@Torxed 已经涵盖了大多数选项......
猜你喜欢
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 1970-01-01
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多