Почему после записи в файл os.path.getsize все еще возвращает предыдущий размер? - PullRequest
13 голосов
/ 18 июня 2009

Я пытаюсь разбить большой 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 вывод в буфере перед его фактическим выводом?

Ответы [ 5 ]

11 голосов
/ 28 апреля 2011

Размер файла отличается от позиции файла. Например,

os.path.getsize('sample.txt') 

Он точно возвращает размер файла в байтах.

Но

f = open('sample.txt')
print f.readline()
f.tell() 

Здесь f.tell () возвращает текущую позицию обработчика файла - то есть, куда при следующей записи будут помещены его данные. Поскольку он знает о буферизации, он должен быть точным, если вы просто добавляете файл вывода.

10 голосов
/ 18 июня 2009

Да, 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, но этого должно быть достаточно для простого разбиения на фрагменты.)

5 голосов
/ 06 августа 2009

Вы пытались заменить os.path.getsize на os.tell, например:

f2.write(line)
size = f2.tell()
4 голосов
/ 18 июня 2009

Отслеживание размера самостоятельно подойдет для вашего случая. Другой способ - очистить файловые буферы перед проверкой размера:

f2.write(line)
f2.flush()  # <-- buffers are written to disk
size = os.path.getsize('split.xml')

Делая это слишком часто, вы замедляете файловый ввод / вывод, конечно.

1 голос
/ 25 ноября 2011

Чтобы найти смещение до конца файла:

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
...