Это из-за режима 'a'
:
а
Открыть для добавления (запись в конце
файла). Файл создается, если он
не существует. Поток
помещается в конец файла .
а +
Открыть для чтения и добавления
(запись в конце файла). Файл
создан, если он не существует.
исходная позиция файла для чтения
в начале файла, но
Вывод всегда добавляется в конец файла .
http://linux.die.net/man/3/fopen
.
EDIT
Мой ответ выше неверен.
Я уже знал, что зацикливание строк файла использует упреждающее чтение буфера, но я полагал, что truncate () вызовет перемещение указателя файла в конец файла, поскольку, насколько мне известно, усечение файла заключается в записи небольшой последовательности байтов, называемой EOF, означающей конец файла, а режим 'a'
всегда провоцирует запись в конец файла независимо от положения указателя файла. незадолго до момента написания.
Ну, это не так, я должен был проверить, выполнив код. Так что мой ответ заслуживает отрицательного ответа.
Но отрицательное голосование без каких-либо объяснений является потертым и разочаровывающим в том случае, когда ошибка в этом ответе не очевидна.
.
Следующий код показывает, что указатель файла не перемещается в конец файла до действия truncate () .
Чтобы прояснить ситуацию, файл 'fileA' состоит из строк, каждая из которых имеет длину 100 символов (в том числе '\ r \ n), заканчивающихся так (' \ r \ n 'здесь не видны):
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00000100
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00000200
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00000300
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00000400
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00000500
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00000600
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00000700
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00000800
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00000900
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00001000
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00001100
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00001200
....ffffffgggggggggghhhhhhhhhhiiiiiiiiii00001300
............................
код:
print '\n===================== 1 ==================\n'
from os.path import getsize
# length of ecr is 90 :
ecr = 10*'a' + 10*'b' + 10*'c' + 10*'d' + 10*'e' +\
10*'f' + 10*'g' + 10*'h' + 10*'i'
# creation of a file whose length exceeds the reading buffer's size
with open('fileA.txt','wb') as f:
for i in xrange(100,53001,100): # 530 turns of iteration
f.write(ecr + str(i).zfill(8) + '\r\n')
# Length of each written line is 100 :
# 90 (ecr) + 8 (str(i).zfill(8)) + 2 ('\r\n')
# File's length will be 53000
print 'size of fileA before truncating : ',getsize('fileA.txt')
# truncating file at uncontroled position
with open('fileA.txt','a+b') as g:
for line in g:
if '00000800' in line:
print repr(line[78:]),' g.tell()==',g.tell()
# at this point, 800 characters should have been read
# in the file if there wasn't a reading buffer
g.truncate()
print 'size of fileA after truncating : ',getsize('fileA.txt')
результат
===================== 1 ==================
size of fileA before truncating : 53000
'hhiiiiiiiiii00000800\r\n' g.tell()== 8192
size of fileA after truncating : 8192
.
Итак, AKX и Fenisko правы при вызове буфера (однако они не проверяли эту гипотезу больше, чем я), поскольку открытие файла в режиме 'a'
не влияет на действие усечения ) . Я думаю, что это то, что написано в верхнем регистре в следующей выдержке из документа:
file.truncate ([size]) Обрезать
размер файла. Если дополнительный размер
аргумент присутствует, файл
усеченный до (не более) этого размера.
размер по умолчанию соответствует текущей позиции.
СОВРЕМЕННОЕ ПОЛОЖЕНИЕ ФАЙЛА НЕ
ИЗМЕНИТЬ
http://docs.python.org/library/stdtypes.html#file.truncate
До сих пор я никогда не понимал это предложение.
.
Как указывает AKX, размер буфера составляет 8192 .... для первого чтения.
Но для следующих чтений буфер явно 10240 символов:
print '\n=================== 2 ====================\n'
from os.path import getsize
# length of ecr is 90 :
ecr = 10*'a' + 10*'b' + 10*'c' + 10*'d' + 10*'e' +\
10*'f' + 10*'g' + 10*'h' + 10*'i'
# creation of a file whose length exceeds the reading buffer's size
with open('fileA.txt','wb') as f:
for i in xrange(100,53001,100): # 530 turns of iteration
f.write(ecr + str(i).zfill(8) + '\r\n')
# length of each written line is 100
# file's length will be 53000
print 'size of fileA before truncating : ',getsize('fileA.txt')
# truncating file at uncontroled position
with open('fileA.txt','a+b') as g:
for line in g:
if '00008100' in line:
print repr(line[78:]),' g.tell()==',g.tell()
# at this point, 800 characters should have been read
# in the file if there wasn't a reading buffer
g.truncate()
print 'size of fileA after truncating : ',getsize('fileA.txt')
# -----------
print
# creation of a file whose length exceeds the reading buffer's size
with open('fileA.txt','wb') as f:
for i in xrange(100,53001,100): # 530 turns of iteration
f.write(ecr + str(i).zfill(8) + '\r\n')
# length of each written line is 100
# file's length will be 53000
print 'size of fileA before truncating : ',getsize('fileA.txt')
# truncating file at uncontroled position
with open('fileA.txt','a+b') as g:
for line in g:
if '00008200' in line:
print repr(line[78:]),' g.tell()==',g.tell()
# at this point, 800 characters should have been read
# in the file if there wasn't a reading buffer
g.truncate()
print 'size of fileA after truncating : ',getsize('fileA.txt')
# -----------
print
# creation of a file whose length exceeds the reading buffer's size
with open('fileA.txt','wb') as f:
for i in xrange(100,53001,100): # 530 turns of iteration
f.write(ecr + str(i).zfill(8) + '\r\n')
# length of each written line is 100
# file's length will be 53000
print 'size of fileA before truncating : ',getsize('fileA.txt')
# truncating file at uncontroled position
with open('fileA.txt','a+b') as g:
for line in g:
if '00018400' in line:
print repr(line[78:]),' g.tell()==',g.tell()
# at this point, 800 characters should have been read
# in the file if there wasn't a reading buffer
g.truncate()
print 'size of fileA after truncating : ',getsize('fileA.txt')
# -----------
print
# creation of a file whose length exceeds the reading buffer's size
with open('fileA.txt','wb') as f:
for i in xrange(100,53001,100): # 530 turns of iteration
f.write(ecr + str(i).zfill(8) + '\r\n')
# length of each written line is 100
# file's length will be 53000
print 'size of fileA before truncating : ',getsize('fileA.txt')
# truncating file at uncontroled position
with open('fileA.txt','a+b') as g:
for line in g:
if '00018500' in line:
print repr(line[78:]),' g.tell()==',g.tell()
# at this point, 800 characters should have been read
# in the file if there wasn't a reading buffer
g.truncate()
print 'size of fileA after truncating : ',getsize('fileA.txt')
результат
=================== 2 ====================
size of fileA before truncating : 53000
'hhiiiiiiiiii00008100\r\n' g.tell()== 8192
size of fileA after truncating : 8192
size of fileA before truncating : 53000
'hhiiiiiiiiii00008200\r\n' g.tell()== 18432
size of fileA after truncating : 18432
size of fileA before truncating : 53000
'hhiiiiiiiiii00018400\r\n' g.tell()== 18432
size of fileA after truncating : 18432
size of fileA before truncating : 53000
'hhiiiiiiiiii00018500\r\n' g.tell()== 28672
size of fileA after truncating : 28672
.
Кстати, truncate () не закрывает файл:
print '\n=================== 3 ====================\n'
from os.path import getsize
# length of ecr is 90 :
ecr = 10*'a' + 10*'b' + 10*'c' + 10*'d' + 10*'e' +\
10*'f' + 10*'g' + 10*'h' + 10*'i'
# creation of a file whose length exceeds the reading buffer's size
with open('fileA.txt','wb') as f:
for i in xrange(100,53001,100): # 530 turns of iteration
f.write(ecr + str(i).zfill(8) + '\r\n')
# length of each written line is 100
# file's length will be 53000
print 'size of fileA before truncating : ',getsize('fileA.txt')
with open('fileA.txt','a+b') as g:
for line in g:
if '00000200' in line:
print repr(line[78:]),' g.tell()==',g.tell()
# at this point, 800 characters should have been read
# if there wasn't a buffer
g.truncate()
g.seek(6000,0)
k = 0
for li in g:
k+=1
print 'k==',k,' ',repr(li[-32:])
if k==7:
break
print 'size of fileA after truncating : ',getsize('fileA.txt')
результат
=================== 3 ====================
size of fileA before truncating : 53000
'hhiiiiiiiiii00000200\r\n' g.tell()== 8192
k== 1 'gghhhhhhhhhhiiiiiiiiii00006100\r\n'
k== 2 'gghhhhhhhhhhiiiiiiiiii00006200\r\n'
k== 3 'gghhhhhhhhhhiiiiiiiiii00006300\r\n'
k== 4 'gghhhhhhhhhhiiiiiiiiii00006400\r\n'
k== 5 'gghhhhhhhhhhiiiiiiiiii00006500\r\n'
k== 6 'gghhhhhhhhhhiiiiiiiiii00006600\r\n'
k== 7 'gghhhhhhhhhhiiiiiiiiii00006700\r\n'
size of fileA after truncating : 8192
Но если инструкция для записи помещается сразу после truncate () , поведение программы становится непоследовательным. Попробуй.