2010-06-12 2 views
8

Я пишу программу списка дел. Он хранит файл с вещью для каждой строки и позволяет пользователю добавлять или удалять элементы. Проблема в том, что по какой-то причине в конце файла я получаю много нулевых байтов, даже если элемент правильно удален. Я покажу вам пару скриншотов, чтобы убедиться, что я проясняю.Запись в файл в Python вставляет нулевые байты

Это файл в 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() 

Не могли бы вы указать, где ошибка?

ответ

9

Мне кажется, что вы забываете перемотать свой поток файлов. После f.truncate(0), добавьте f.seek(0). В противном случае, я думаю, ваша следующая запись попытается начать с позиции, с которой вы остановились, заполнив нулевые байты на своем пути.

(Обратите внимание, что количество нулевых символов в вашем примере равно количеству символов в ваших удаленных строк плюс возврат каретки и перевод строки символов для каждого из них.)

6

Из Python manual:

file.truncate([size])
Усекать размер файла. Если присутствует необязательный аргумент , файл усекается до (не более) этого размера. Размер по умолчанию соответствует текущей позиции. Текущее положение файла не изменяется. Обратите внимание, что если указанный размер превышает текущий размер файла, результат зависит от платформы: возможности включают в себя, что файл может оставаться неизменным, увеличиваться до указанного размера, как если бы он был заполнен нулем, или увеличиваться до указанного размера с неопределенным новым контентом , Доступность: Windows, много вариантов Unix.

Вы обрезаете файл, а затем пишите item1 и item2 в прежнем конце файла. Все, что до этого заканчивается, заполняется 0 байтами.

f.seek(0) 

Позвоните, чтобы сбросить положение файла после усечения.

+0

Большое спасибо. Ваш ответ был так же хорош, как и Лес, но я должен был выбрать один, чтобы принять, поэтому я выбрал более ранний. Ничего личного. – Javier

3

Подсказка. Не делай этого.

В старину (30 лет назад - серьезно) мы «обновили» файлы со сложной логикой добавления/изменения/удаления.

В настоящее время, жизнь проще, если вы пишете программы, которые

  1. Читать весь файл в память.

  2. Работы на объектах в памяти.

  3. Периодически записывайте объекты в файл и когда пользователь хочет сохранить.

Это быстрее и проще. Используйте pickle, чтобы сбрасывать ваши объекты в файл. Не связывайтесь с «записями» или любой попыткой изменить файл «на месте».

Если вы действительно считаете, что вам нужны возможности SQL (вставка, обновление, удаление), используйте SQLite. Это более надежно, чем то, что вы пытаетесь сделать.

+1

Это было для практики, но это интересный момент. Я посмотрю, если я изменю его, чтобы вести себя так, как вы говорите. – Javier

Смежные вопросы