Итак, вы хотите заменить каждый ОДИН символ '#'
ОДНЫМ символом ' '
, верно?
Тогда это легко сделать, поскольку вы можете заменить любую часть файла строкой с одинаковыми значениями.длина без нарушения организации файла.
Повторение такой замены позволяет произвести преобразование фрагмента файла в фрагмент;поэтому вы избегаете чтения всего файла в памяти, что проблематично, если файл очень большой.
Вот код на Python 2.7.
Возможно, замена фрагмента на фрагмент будет неэффективнойчтобы сделать это быстрее, и вам будет трудно писать то же самое на C ++.Но в целом, когда я предлагал такие коды, это удовлетворительно увеличило время выполнения.
def treat_file(file_path, chunk_size):
from os import fsync
from os.path import getsize
file_size = getsize(file_path)
with open(file_path,'rb+') as g:
fd = g.fileno() # file descriptor, it's an integer
while True:
x = g.read(chunk_size)
g.seek(- len(x),1)
g.write(x.replace('#',' '))
g.flush()
fsync(fd)
if g.tell() == file_size:
break
Комментарии:
open(file_path,'rb+')
абсолютно необходимо открыть файл в двоичном режиме 'b' , чтобы точно контролировать положения и перемещения указателя файла;
mode '+' для возможности чтения и записи в файл
fd = g.fileno()
дескриптор файла, это целое число
x = g.read(chunk_size)
чтениякусок размером chunk_size .Было бы сложно дать ему размер буфера чтения, но я не знаю, как найти размер этого буфера.Следовательно, хорошей идеей является присвоить ему значение 2.
g.seek(- len(x),1)
указатель файла перемещается обратно в положение, из которого только что было выполнено чтение фрагмента.Это должно быть len(x)
, а не chunk_size , потому что последнее чтение фрагмента обычно меньше, чем chink_size
g.write(x.replace('#',' '))
записи на той же длине с измененнымchunk
g.flush()
fsync(fd)
эти две инструкции форсируют запись, в противном случае измененный кусок может остаться в буфере записи и записаться в неуправляемый момент
if g.tell() >= file_size: break
после чтения последней части файланезависимо от его длины (меньше или равно chunk_size), указатель файла находится на максимальной позиции файла, то есть file_size , и программа должна остановиться
.
В случае, если вы хотите заменить несколько последовательных '### ...' только на один, код легко модифицируется, чтобы соответствовать этому требованию, так как запись сокращенного фрагмента не стирает символы, которые еще не прочитаны, более далеко вфайл.Для этого нужны только 2 указателя на файлы.