Является ли эта процедура python file.seek() правильной?
Эта процедура выглядит хорошо для меня, но в конечном итоге записывает мусор в файл. lines_of_interest
это набор строк (896227L
, 425200L
, 640221L
и т. д.) которые необходимо изменить в файле. Процедура if else определяет, что будет изменено в этой строке. Это первый раз, когда я использовал seek()
но поверьте, синтаксис правильный. Может ли кто-нибудь определить какие-либо ошибки в коде, которые заставят его работать правильно?
outfile = open(OversightFile, 'r+')
for lines in lines_of_interest:
for change_this in outfile:
line = change_this.decode('utf8', 'replace')
outfile.seek(lines)
if replacevalue in line:
line = line.replace(replacevalue, addValue)
outfile.write(line.encode('utf8', 'replace'))
break#Only check 1 line
elif not addValue in line:
#line.extend(('_w\t1\t'))
line = line.replace("\t\n", addValue+"\n")
outfile.write(line.encode('utf8', 'replace'))
break#Only check 1 line
outfile.close()
2 ответа
Вы должны думать о файлах как о неизменяемых (если вы не хотите добавлять в файл). Если вы хотите изменить существующие строки в файле, выполните следующие действия:
- Прочитайте каждую строку из вашего входного файла, например, data.txt
- Запишите каждую строку, включая измененные строки, в выходной файл, например, new_file.txt
- Удалить входной файл.
- Переименуйте выходной файл в имя входного файла.
Одна из проблем, с которой вам не нужно сталкиваться на шаге 2), - это попытаться придумать имя файла, которого еще не существует. Модуль tempfile сделает это за вас.
Модуль fileinput может использоваться для прозрачного выполнения всех этих шагов:
#1.py
import fileinput as fi
f = fi.FileInput('data.txt', inplace=True)
for line in f:
print "***" + line.rstrip()
f.close()
--output:--
$ cat data.txt
abc
def
ghi
$ python 1.py
$ cat data.txt
***abc
***def
***ghi
Модуль fileinput открывает заданное вами имя файла и переименовывает файл. Затем операторы печати направляются в пустой файл, созданный с оригинальным именем. Когда вы закончите, переименованный файл будет удален (или вы можете указать, что он должен остаться).
Вы оба циклически просматриваете файл и ищете его несколько раз, но никогда не сбрасываете позицию перед повторным чтением.
На первой итерации вы читаете первую строку, затем ищите в другом месте файла, записываете в эту позицию, затем break
вне for change_this in out_file:
петля.
Следующая итерация for lines in lines_of_interest:
цикл затем начинает читать с outfile
еще раз, но файл теперь расположен в точке, где последний outfile.write()
остановился Это означает, что вы сейчас читаете все, что следовали только что написанным данным.
Это, вероятно, не то, что вы хотели сделать.
Если вы хотите прочитать строку из той же позиции и записать ее обратно в то же место, вам нужно сначала выполнить поиск и использовать .readline()
вместо итерации, чтобы прочитать вашу строку. Затем ищите снова, прежде чем писать:
outfile = open (OversightFile, 'r +')
for position in lines_of_interest:
outfile.seek(position)
line = outfile.readline().decode('utf8', 'replace')
outfile.seek(position)
if replacevalue in line:
line = line.replace(replacevalue, addValue)
outfile.write(line.encode('utf8'))
elif not addValue in line:
line = line.replace("\t\n", addValue+"\n")
outfile.write(line.encode('utf8')
Тем не менее, обратите внимание, что если вы записываете данные, которые короче или длиннее исходной строки, размер файла не будет корректироваться! Запись более длинной строки перезапишет первые символы следующей строки, более короткая запись оставит завершающие символы старой строки в файле.