Запись в файл в Python вставляет пустые байты

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

Это - файл в Блокноте ++ прежде, чем запустить программу:

Normal todo list

Это - файл после удаления объекта 3 (рассчитывающий от 1):

Item 3 is gone, but there are NUL bytes

Это - соответствующие нормы. Фактическая программа больше, но выполняющий просто эту часть инициировал ошибку.

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

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

8
задан Glorfindel 29 July 2019 в 11:07
поделиться

3 ответа

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

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

9
ответ дан 5 December 2019 в 09:24
поделиться

Поймите намек. Не делай этого.

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

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

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

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

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

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

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

3
ответ дан 5 December 2019 в 09:24
поделиться

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

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

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

f.seek(0)

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

6
ответ дан 5 December 2019 в 09:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: