Depois de escrever para um arquivo, por que os.path.getsize ainda retornar ao tamanho anterior?

StackOverflow https://stackoverflow.com/questions/1013778

  •  06-07-2019
  •  | 
  •  

Pergunta

Eu estou tentando dividir um grande arquivo xml em pedaços menores. Eu escrevo para o arquivo de saída e, em seguida, verificar o seu tamanho para ver se o seu passado de um limite, mas eu não acho que o método getSize () está funcionando como esperado.

O que seria uma boa maneira de obter o tamanho do arquivo de um arquivo que está mudando de tamanho.

Ive feito algo assim ...

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

A execução deste impressões 0 como o tamanho do arquivo para cerca de 80 iterações e depois 4176. Does Python armazenar a saída em um buffer antes de realmente produzir isso?

Foi útil?

Solução

Sim, Python é amortecer sua saída. Você seria melhor fora de rastreamento do tamanho mesmo, algo como isto:

size = 0
for line in f1:
  if str(line) == '</Service>\n':
    break
  else:
    f2.write(line)
    size += len(line)
    print('size = ' + str(size))

(que pode não ser 100% exato, por exemplo. No Windows cada linha vai ganhar um byte por causa da linha separadora \r\n, mas deve ser bom o suficiente para simples chunking.)

Outras dicas

tamanho do arquivo é diferente da posição do arquivo. Por exemplo,

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

É exatamente retorna tamanho do arquivo em bytes.

Mas

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

Aqui f.tell () retorna a posição atual do manipulador de arquivo - ou seja, onde a próxima gravação irá colocar seus dados. Uma vez que é ciente do buffer, deve ser preciso, desde que você está simplesmente acrescentar ao arquivo de saída.

Você tentou substituir os.path.getsize com os.tell, como este:

f2.write(line)
size = f2.tell()

Acompanhamento do tamanho mesmo vai ser bom para o seu caso. Uma forma diferente seria a de liberar os buffers de arquivo antes de você verificar o tamanho:

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

Fazer isso muitas vezes vai abrandar o arquivo de I / O, é claro.

Para encontrar o deslocamento para o final de um arquivo:

file.seek(0,2)
print file.tell()

exemplo do mundo real - leia as atualizações para um arquivo e imprimi-los como eles acontecem:

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top