Наилучшая производительность почти всегда будет достигнута, если написать новую версию файла и затем атомарно записать старую версию, поскольку файловые системы сильно оптимизированы для такого последовательного доступа, как и базовое оборудование (за возможным исключением).некоторых из новейших SSD
s, но даже тогда это сомнительное предложение).Кроме того, это позволяет избежать уничтожения данных в случае сбоя системы в любое время - у вас остается либо старая версия файла без изменений, либо новая на его месте.Поскольку каждая система может всегда аварийно завершать работу в любое время (и, согласно закону Мерфи, она выберет самый неудачный момент ;-), целостность данных обычно считается очень важной (часто данные более ценны, чем система, на которой они работают).который хранится - следовательно, «зеркалирование» решений RAID для защиты от сбоев disk с потерей ценных данных; -).
Если вы принимаете этот вменяемый подход, общая идея такова: открыть старыефайл для чтения, новый для записи (создания);скопировать N1 байтов из старого файла в новый;затем пропустите N2 байта старого файла;затем скопируйте остальные;закройте оба файла;атомно переименовать новое в старое.(Очевидно, в Windows нет системного вызова «атомарного переименования», используемого из Python - чтобы сохранить целостность в этом случае, вместо атомарного переименования вы должны сделать три шага: переименовать старый файл в имя резервной копии, переименовать новый файл в старый,удалить файл с именем резервной копии - в случае сбоя системы во время второй из этих трех очень быстрых операций достаточно одного переименования, чтобы восстановить целостность данных.
N1 и N2, конечно,два параметра, указывающие, где начинается удаленная часть, и как долго это будет.Для части об открытии файлов операторы with open('old.dat', 'rb') as oldf:
и with open('NEWold.dat', 'wb') as newf:
, вложенные друг в друга, явно лучше (остальная часть кода до шага переименования должна быть вложена в обоих из них, конечно).
Для шага «копировать все остальное» лучше всего подойдет shutil.copyfileobj (не забудьте указать длину буфера, которая будет удобно помещаться в вашей доступной ОЗУ, но большой один будет иметь тенденцию давать лучшую производительность).Шаг "пропустить" - это всего лишь seek
для объекта файла oldf
open-for-read.Для копирования ровно N1 байта из oldf в newf прямая поддержка в стандартной библиотеке Python отсутствует, поэтому вы должны написать свою собственную, например:
def copyN1(oldf, newf, N1, buflen=1024*1024):
while N1:
newf.write(oldf.read(min(N1, buflen)))
N1 -= buflen