【问题标题】:python cannot write to file after saved in another editorpython在另一个编辑器中保存后无法写入文件
【发布时间】:2018-04-03 09:09:51
【问题描述】:

我有一个连续运行的 python 文件,偶尔会通过键盘输入写入文件。

但是,如果我在另一个编辑器中编辑文件(使用例如 sed 或 head 或 gedit)然后再次保存,我的 python 程序不再写入文件,即使(使用 gedit 时)我退出编辑。

继续写入文件的正确方法是什么? 这是一个例子

import sys
f = open('tmp.txt', 'ab')
while 1:
   raw_input()
   f.write('this is a test\n')
    f.flush()
f.close()

例子:

python tmp.py
(enter input) #writes line to file
[ in a separate terminal ] sed -i '$ d' tmp.txt #deletes last line in file
(enter input to python in terminal) #no longer writes to file

【问题讨论】:

  • 也许你需要在写作之前寻找到最后。 f.seek(0, os.SEEK_END)
  • 也许您需要现实一点,并表明您没有在 (enter ...(enter ...) 之间运行 sed -i ...,而是在不同的终端中运行。否则,您将停止脚本并重新启动它。
  • 抱歉没有说清楚,我确实在单独的终端中运行我的文件编辑。彼得:这可能也是问题的一部分,我明天会调查最终原因是什么。谢谢!

标签: python file output


【解决方案1】:

您的操作系统管理文件的读/写访问权限。当您第一次在循环外获得对文件的写访问权时,一旦它被另一个进程或线程占用,您将永远无法将其返回到循环内。所以在你的循环中设置文件对象。

import sys

while True :
    raw_input()
    with open('tmp.txt', 'ab') as f :
        f.write('this is a test\n')

对于文件对象,建议使用上下文管理器 (with-Statement)。它会自动打开和关闭对象。

【讨论】:

  • 哇,是的,这可能是问题所在,尽管我明天必须进去测试一下。现在回想起来,我感到“doh!” - 简化它肯定会让回想起来很明显(用线程和 Tkinter 做东西)。昨天我刚刚通过使用 "$ n=4 $ tac tmp.txt | sed "1,$n{d}" | tac > out.txt; cat out.txt > tmp.txt" 解决了这个问题,它不会以与我的脚本能够继续写入文件相同的方式干扰文件(你知道有什么区别吗?)
  • @orangenarwhals:您的命令行永远不会更改与文件名关联的inode(> somefile 截断现有的somefile 然后写入新数据,它不会删除 i> 表示文件,然后创建一个新文件)。大多数编辑器使用崩溃安全的编辑形式,其中一个新文件被完全写入,然后发出原子重命名操作,将新文件重命名为旧文件名(隐式删除旧文件)。但这意味着每次保存操作后inode编号都会发生变化,这意味着来自其他程序的打开文件句柄无效)。
  • “写入新文件,重命名以替换旧文件”的好处是,如果您在重命名之前的任何时候断电(或蓝屏,或程序崩溃),您的原始文件文件数据完好无损。在任何情况下,最终文件都只包含 complete 旧数据或 complete 新数据。如果您的计算机在cat out.txt > tmp.txt 步骤期间崩溃,或者您在处理过程中将其杀死,则tmp.txt 可能包含部分写入的垃圾,或者根本没有,并且可能无法判断out.txttmp.txt 是“正确的”数据。
  • @orangenarwhals 如果我的回答符合您的预期,请随时接受。
【解决方案2】:
import sys

while True :
    with open('tmp.txt', 'ab') as f :
        f.write('this is a test\n')

【讨论】:

  • 我们几乎同时回答。我快了一点;)...你忘了raw_input()...
  • 我不确定为什么这被否决了,但感谢你们两个把我从深夜“毒品”中解救出来
  • 否决票可能是因为您没有包含任何描述。仅代码的答案有些不受欢迎。如果没有描述,初学者不会知道“秘诀”是您使用while True 而不是while 1,还是with 而不是对open 的正常调用,或者将open 移动到内部循环,或者是因为您删除了对flush 的调用。其中很多对您来说似乎很明显,但对于需要首先提出这个问题的人来说可能不是。
猜你喜欢
  • 2016-12-07
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
相关资源
最近更新 更多