Задать вопрос
@Statium

Python Replace ломает файл. Почему?

Добрый день. Имеется программа которая циклом обновляет файл и работает как служба Windows. В определенный момент, например при внезапного отключения ПК, файл ломается. Ниже код, который отвечает за обновление, причем по логам файл ломается даже не на этапе обновления. Файл в конце закрываю, но это не решило проблему. Как исправить ситуацию?
if delta2.days <= 14:
                            app_log.info('Дата меньше 14 дней')
                            with open('C:\\m\\notice.ini', 'r') as f:
                                old_data = f.read()
                            new_data = old_data.replace('2-0\n', '2-1\n')
                            with open('C:\\m\\notice.ini', 'w') as f:
                                f.write(new_data)
                                f.close()
                        else:
                            app_log.info('Дата больше 14 дней')
                            with open('C:\\m\\notice.ini', 'r') as f:
                                old_data = f.read()
                            new_data = old_data.replace('2-1\n', '2-0\n')
                            with open('C:\\m\\notice.ini', 'w') as f:
                                f.write(new_data)
                                f.close()


Файл такого вида и периодически нужно менять 1-0 на 1-1 и обратно, в зависимости от условий, в целом работает, но при внезапном отключении пк файл крашится и записываются непонятные символы в одну строку.

1-1
2-0
3-0
4-0
5-0
6-0
7-1
  • Вопрос задан
  • 120 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 3
LaRN
@LaRN
Senior Developer
А если не делать REPLACE в имеющемся файле, а создать новый файл, условно C:\\m\\notice_tmp.ini и туда сохранить новую версию содержимого, после чего удалить старый файл, а новый переименовать в C:\\m\\notice.ini.
Ответ написан
@va_k
Замените `f.close()` на `os.fsync(f)`. Менеджер контекста у вас сам закроет файл.
Ответ написан
Комментировать
shabelski89
@shabelski89
engineer
так как никакого трейс лога нет, то я бы предложил чуть быстрее выходить из with open.

delta2_days = 1  # delta2.days
DELTA_DAYS = 14
FILE = r'C:\\m\\notice.ini'
REPLACE_ONE = '2-0\n'
REPLACE_TWO = '2-1\n'

def read_file(filename: str):
    with open(filename, 'r') as f:
        return f.read()


def write_file(filename: str, data):
    with open(filename, 'w') as f:
        f.write(data)


print(f'Дата {"меньше" if delta2_days <= DELTA_DAYS else "больше "} 14 дней')
# app_log.info(f'Дата {"больше" if some > DELTA_DAYS else "меньше"} 14 дней')
old_data = read_file(FILE)
new_data = old_data.replace(REPLACE_ONE, REPLACE_TWO) if delta2_days <= DELTA_DAYS else old_data.replace(REPLACE_TWO, REPLACE_ONE)
write_file(FILE, new_data)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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