2010-06-12 35 views
8

我正在编写待办事项列表程序。它为每行保留一个文件,并让用户添加或删除项目。问题在于,由于某种原因,即使该项目被正确删除,我在文件开始时也会产生大量零字节。我会告诉你几个截图,以确保我清楚自己。用Python写入文件会插入空字节

这是在记事本++文件运行程序之前:

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() 

请您指出错误在哪里?

回答

9

它看起来像我忘了倒退你的文件流。在f.truncate(0)之后,添加f.seek(0)。否则,我认为你的下一次写操作会尝试从你停止的位置开始,在那里填写空字节。

(注意的是,在您的示例空字符的数目等于字符数在已删除的行加上为每一个回车和换行字符。)

6

Python manual

file.truncate([size])
截断文件的大小。如果存在可选的大小参数,则该文件被截断为(最多)该大小。大小默认为当前位置。 当前文件位置不变。请注意,如果指定的大小超出文件的当前大小,则结果将取决于平台:可能性包括文件可能保持不变,增加到指定的大小,就像零填充一样,或者增加到具有未定义新内容的指定大小。可用性:Windows,许多Unix变体。

您正在截断文件,然后在文件的前端写入item1和item2。之前的所有内容都以0字节填充。

f.seek(0) 

调用此函数重置截断后的文件位置。

+0

非常感谢。你的答案和森林一样好,但我必须选择一个接受,所以我选择了较早的一个。与个人无关。 – Javier 2010-06-12 22:52:37

3

采取提示。不要这样做。

在过去的日子里(30年前 - 严肃地说)我们用复杂的添加/更改/删除逻辑“更新”文件。

如今,如果你编写的程序

  1. 将整个文件读入内存的生活更简单。

  2. 处理内存中的对象。

  3. 定期将对象写入文件,并在用户想要保存时写入。

它更快更简单。使用pickle将您的对象转储到文件。不要混淆“记录”或尝试更改文件“到位”。

如果你真的认为你需要SQL功能(插入,更新,删除),然后使用SQLite。它比你想要做的更可靠。

+1

这是为了练习,但这是一个有趣的观点。我会看看我是否改变它的行为像你说的。 – Javier 2010-06-12 23:51:30