Запись в файл в Python вставляет нулевые байты - PullRequest
8 голосов
/ 13 июня 2010

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

Это файл в Notepad ++ перед запуском программы:

Обычный список задач http://img683.imageshack.us/img683/2812/beforew.png

Это файл после удаления элемента 3 (считая от 1):

Элемент 3 пропал, но есть NUL-байты 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()

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

Ответы [ 3 ]

9 голосов
/ 13 июня 2010

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

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

6 голосов
/ 13 июня 2010

Из руководства Python :

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

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

f.seek(0)

Вызовите это для сброса позиции файла после усечения.

3 голосов
/ 13 июня 2010

Возьмите подсказку. Не делай этого.

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

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

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

  2. Работа с объектами в памяти.

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...