Благодаря пути файловые системы работают, вы не можете просто удалить строки из файла непосредственно. Любой способ сделать это обязательно включает в себя переписывание всего файла с удалением удаленных строк.
Чтобы быть в безопасности, перед удалением старого файла вы хотите временно сохранить новый файл, пока не убедитесь, что новый был успешно создан. И если вы хотите избежать чтения всего большого файла в память, вы захотите использовать генератор.
Вот генератор, который возвращает каждый элемент из итератора (например, файл-подобный объект) после определенного количества элементов уже вернулись:
def gen_after_x(iterable, x):
# Python 3:
yield from (item for index,item in enumerate(iterable) if index>=x)
# Python 2:
for index,item in enumerate(iterable):
if index>=x:
yield item
Чтобы сделать вещи проще, мы создадим функция для записи временного файла:
def write_file(fname, lines):
with open(fname, 'w') as f:
for line in lines:
f.write(line + '\n')
Мы также потребуются os.remove
и os.rename
функции из модуля os
удалить исходный файл и переименовать временный файл. И нам понадобится copyfile
от shutil
, чтобы сделать копию, чтобы мы могли безопасно удалить исходный файл.
Теперь соберем все вместе:
from os import remove, rename
from shutil import copyfile
src_file = 'big_file'
tmp_file = 'big_file_temp'
skip = 2
with open(src_file) as fin:
olines = gen_after_x(fin, skip)
write_file(tmp_file, olines)
src_file_copy = src_file + '_copy'
copyfile(src_file, src_file_copy)
try:
remove(src_file)
rename(tmp_file, src_file)
remove(src_file_copy)
except Exception:
try:
copyfile(src_file_copy, src_file)
remove(src_file_copy)
remove(tmp_file)
except Exception:
pass
raise
Однако, я хотел бы отметить, что 240 МБ не такой огромный файл в эти дни; вы можете найти его быстрее сделать это обычным способом, так как это сокращает повторяющиеся записи на диск:
src_file = 'big_file'
tmp_file = 'big_file_temp'
skip = 2
with open(src_file) as f:
lines = f.readlines()
for _ in range(skip):
lines.pop(0)
with open(tmp_file, 'w') as f:
f.write('\n'.join(lines))
src_file_copy = src_file + '_copy'
copyfile(src_file, src_file_copy)
try:
remove(src_file)
rename(tmp_file, src_file)
remove(src_file_copy)
except Exception:
try:
copyfile(src_file_copy, src_file)
remove(src_file_copy)
remove(tmp_file)
except Exception:
pass
raise
... или если вы предпочитаете более рискованный путь:
with open(src_file) as f:
lines = f.readlines()
for _ in range(skip):
lines.pop(0)
with open(src_file, 'w') as f:
f.write('\n'.join(lines))
Он работал так, как я хотел ... – Abx