Después de escribir en un archivo, ¿por qué os.path.getsize aún devuelve el tamaño anterior?

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

  •  06-07-2019
  •  | 
  •  

Pregunta

Estoy tratando de dividir un archivo xml grande en trozos más pequeños. Escribo en el archivo de salida y luego verifico su tamaño para ver si ha pasado un umbral, pero no creo que el método getsize () funcione como se esperaba.

¿Cuál sería una buena manera de obtener el tamaño de archivo de un archivo que está cambiando de tamaño?

He hecho algo como esto ...

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

ejecutar esto imprime 0 como el tamaño del archivo durante aproximadamente 80 iteraciones y luego 4176. ¿Python almacena la salida en un búfer antes de emitirla realmente?

¿Fue útil?

Solución

Sí, Python está almacenando en búfer su salida. Sería mejor que rastrearas el tamaño tú mismo, algo como esto:

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

(Eso podría no ser 100% exacto, por ejemplo, en Windows cada línea ganará un byte debido al separador de línea \ r \ n , pero debería ser lo suficientemente bueno para un simple corte).

Otros consejos

El tamaño del archivo es diferente de la posición del archivo. Por ejemplo,

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

Devuelve exactamente el tamaño del archivo en bytes.

Pero

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

Aquí f.tell () devuelve la posición actual del controlador de archivos, es decir, donde la próxima escritura colocará sus datos. Dado que es consciente del almacenamiento en búfer, debe ser preciso siempre que simplemente añada al archivo de salida.

¿Has intentado reemplazar os.path.getsize con os.tell, así:

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

El seguimiento del tamaño usted mismo estará bien para su caso. Una forma diferente sería vaciar los búferes de archivos justo antes de verificar el tamaño:

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

Hacerlo con demasiada frecuencia ralentizará la E / S de archivos, por supuesto.

Para encontrar el desplazamiento al final de un archivo:

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

Ejemplo del mundo real: lea las actualizaciones de un archivo e imprímalas a medida que ocurren:

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top