我正在写一个待办事项列表程序。它使每行保存一个文件,并允许用户添加或删除项目。问题是,由于某种原因,即使正确删除了项目,我最终会在文件的开头有很多零字节。我将向您展示一些屏幕截图,以确保我清楚自己。
在运行程序之前,这是Notepad ++中的文件:
Normal todo list http://img683.imageshack.us/img683/2812/beforew.png
这是删除第3项(从1开始计算)后的文件:
Item 3 is gone, but there are NUL bytes http://img190.imageshack.us/img190/9387/afterj.png
这是相关代码。实际程序更大,但仅运行此部分会触发错误。
import os
TODO_FILE = r"E:\javi\code\Python\todo-list\src\todo.txt"
def del_elems(f, delete):
"""Takes an open file and either a number or a list of numbers, and deletes the
lines corresponding to those numbers (counting from 1)."""
if isinstance(delete, int):
delete = [delete]
lines = f.readlines()
f.truncate(0)
counter = 1
for line in lines:
if counter not in delete:
f.write(line)
counter += 1
f = open(TODO_FILE, "r+")
del_elems(f, 3)
f.close()
你能指出哪里出错了吗?
答案 0 :(得分:9)
在我看来,您忘记了回放文件流。在f.truncate(0)
之后,添加f.seek(0)
。否则,我认为你的下一次写操作将尝试从你离开的位置开始,在那里填充空字节。
(请注意,示例中的空字符数等于已删除行中的字符数加上每个字符的回车符和换行符。)
答案 1 :(得分:6)
file.truncate([size])
截断文件的大小。如果存在可选的 size 参数,则该文件将截断为(最多)该大小。大小默认为当前位置。 当前文件位置未更改。请注意,如果指定的大小超过文件的当前大小,则结果取决于平台:可能包括文件可能保持不变,增加到指定的大小,就好像零填充,或使用未定义的新内容增加到指定的大小。可用性:Windows,许多Unix变体。
您正在截断文件,然后在文件的前一端写入item1和item2。之前的所有内容都以0字节填充。
f.seek(0)
调用此方法以在截断后重置文件位置。
答案 2 :(得分:3)
接受提示。不要这样做。
在过去(30年前 - 认真),我们使用复杂的添加/更改/删除逻辑“更新”了文件。
如今,如果编写
程序,生活会更简单将整个文件读入内存。
处理内存中的对象。
定期将对象写入文件,并在用户想要保存时。
它更快更简单。使用pickle
将对象转储到文件中。不要乱用“记录”或任何“就地”更改文件的尝试。
如果您确实认为需要SQL功能(插入,更新,删除),请使用SQLite。它比你试图做的更可靠。