Удаление произвольного фрагмента файла - PullRequest
3 голосов
/ 22 августа 2010

Каков наиболее эффективный способ удаления произвольного фрагмента файла с учетом начального и конечного смещений? Я бы предпочел использовать Python, но я могу вернуться к C, если придется.

Скажите, что это файл

..............xxxxxxxx----------------

Я хочу удалить кусок:

..............[xxxxxxxx]----------------

После операции оно должно стать:

..............----------------

Чтение всего этого в память и манипулирование им в памяти неосуществимо.

Ответы [ 3 ]

4 голосов
/ 22 августа 2010

Наилучшая производительность почти всегда будет достигнута, если написать новую версию файла и затем атомарно записать старую версию, поскольку файловые системы сильно оптимизированы для такого последовательного доступа, как и базовое оборудование (за возможным исключением).некоторых из новейших 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
0 голосов
/ 22 августа 2010

Попробуйте mmap файл. Это не обязательно прочитает все это в памяти сразу.

Если вы действительно хотите сделать это вручную, выберите какой-то размер куска и выполняйте чтение и запись назад и вперед. Но ищущие убьют тебя ...

0 голосов
/ 22 августа 2010

Я бы предложил отображение памяти . Хотя это на самом деле манипулирование файлом в памяти , это более эффективно, чем простое чтение всего файла в память.

Что ж, вы должны так или иначе манипулировать содержимым файла в памяти, так как нет никаких системных вызовов для такой операции ни в * nix, ни в Win (по крайней мере, я об этом не знаю).

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