Вы можете искать отрицательный индекс, если передаете аргумент fromce в file.seek
, в противном случае он считается абсолютным (поэтому отрицательные местоположения не допускаются).
import os
f = open('insert.txt', 'r+')
f.seek(3)
f.seek(-1, os.SEEK_CUR) # will go back one position
f.seek(-1, os.SEEK_END) # one position before the end of the file
Это вам не очень поможет - запись байтов в середине перезапишет существующие байты, а не перетасовывает все вперед.
Вы можете достичь того, что хотите, зарезервировав фиксированное количество байтов заголовка в начале файла - это то, как двоичные форматы файлов избегают необходимости записывать целые файлы при их изменении.Я не рекомендовал бы это для исходных файлов, все же.Это было бы довольно подвержено ошибкам - если вы ошиблись (или заголовок, который вы хотели написать, получили слишком длинный), тогда начало вашего кода могло бы быть перезаписано сценарием обслуживания заголовка.
Гибридный подходможет работать, хотя.
- При первой обработке файлов медленно пишите заголовок (снова записывая весь файл), резервируя некоторое дополнительное пространство для будущего роста, и ставьте страж в конце заголовка.Часовой должен быть чем-то удобочитаемым, чтобы его можно было случайно не сломать.
- Затем, в следующий раз, когда вам нужно написать заголовок, прочитайте его (до нужной вам длины).Если страж находится в нужном месте, вы можете использовать технику быстрой перезаписи.
- Если нет, вам нужно снова написать заголовок медленным способом.
Некоторый код (который нене обрабатывает изменение размера заголовка):
import sys
import os
RESERVED = 40
SENTINEL = '\n### HEADER ENDS ###\n'
def pad(heading):
free_space = RESERVED - len(heading)
padding = ('#' * free_space) if free_space > 0 else ''
return heading + padding
def _write_header_slow(fname, text):
# Do this in chunks instead if you have large files.
dest = fname + '.temp'
with open(fname) as infile:
content = infile.read()
with open(dest, 'w') as outfile:
outfile.write(text)
outfile.write(SENTINEL)
outfile.write(content)
os.rename(dest, fname)
def write_header(fname, text):
if not text.endswith('\n'):
text += '\n'
assert len(text) < RESERVED, 'too much for the header!'
padded = pad(text)
with open(fname, 'rb+') as f:
current_header = f.read(RESERVED + len(SENTINEL))
if current_header.endswith(SENTINEL):
f.seek(0)
print 'fast path!'
f.write(padded)
else:
print 'slow path ):'
_write_header_slow(fname, text)
if __name__ == '__main__':
write_header(sys.argv[1], sys.argv[2])