После записи в файл, почему os.path.getsize все еще возвращает предыдущий размер?
Я пытаюсь разделить большой XML файл на более мелкие куски. Я пишу в выходной файл, а затем проверяю его размер, чтобы узнать, прошел ли он порог, но я не думаю, что метод getsize() работает как ожидалось.
Что было бы хорошим способом получить размер файла, который изменяется в размере.
Я сделал что-то вроде этого...
import string
import os
f1 = open('VSERVICE.xml', 'r')
f2 = open('split.xml', 'w')
for line in f1:
if str(line) == '</Service>\n':
break
else:
f2.write(line)
size = os.path.getsize('split.xml')
print('size = ' + str(size))
выполняется эта печать 0 как размер файла для примерно 80 итераций, а затем 4176. Сохраняет ли Python вывод в буфере до его фактического вывода?
Ответы
Ответ 1
Да, Python выполняет буферизацию вашего вывода. Вам лучше отслеживать размер самостоятельно, что-то вроде этого:
size = 0
for line in f1:
if str(line) == '</Service>\n':
break
else:
f2.write(line)
size += len(line)
print('size = ' + str(size))
(Это может быть не на 100% точным, например, в Windows каждая строка будет получать байт из-за разделителя строк \r\n
, но он должен быть достаточно хорош для простого chunking.)
Ответ 2
Размер файла отличается от положения файла. Например,
os.path.getsize('sample.txt')
Он точно возвращает размер файла в байтах.
Но
f = open('sample.txt')
print f.readline()
f.tell()
Здесь f.tell() возвращает текущую позицию обработчика файла - то есть, где следующая запись будет помещать свои данные. Поскольку он знает о буферизации, он должен быть точным, если вы просто добавляете к выходному файлу.
Ответ 3
Вы пытались заменить os.path.getsize на os.tell, например:
f2.write(line)
size = f2.tell()
Ответ 4
Отслеживание размера самостоятельно будет в порядке для вашего дела. Другой способ - очистить файловые буферы непосредственно перед проверкой размера:
f2.write(line)
f2.flush() # <-- buffers are written to disk
size = os.path.getsize('split.xml')
Выполнение этого слишком часто замедляет работу файлов ввода/вывода, конечно.
Ответ 5
Чтобы найти смещение в конце файла:
file.seek(0,2)
print file.tell()
Пример реального мира - читайте обновления в файле и печатайте их по мере их возникновения:
file = open('log.txt', 'r')
#find inital End Of File offset
file.seek(0,2)
eof = file.tell()
while True:
#set the file size agian
file.seek(0,2)
neweof = file.tell()
#if the file is larger...
if neweof > eof:
#go back to last position...
file.seek(eof)
# print from last postion to current one
print file.read(neweof-eof),
eof = neweof