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 tamaño de archivo durante aproximadamente 80 iteraciones y luego 4176. ¿Python almacena la salida en un búfer antes de emitirla realmente?

13
Maulin 18 jun. 2009 a las 20:38

5 respuestas

La mejor respuesta

Sí, Python está almacenando en búfer tu 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))

(Es posible que eso no sea 100% preciso, 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).

10
RichieHindle 18 jun. 2009 a las 16:41

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
1
Zv_oDD 25 nov. 2011 a las 11:58

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

f2.write(line)
size = f2.tell()
5
Piotr Czapla 6 ago. 2009 a las 14:26

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 archivo, por supuesto.

4
efotinis 18 jun. 2009 a las 19:16

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 esté agregando al archivo de salida.

11
Community 11 abr. 2012 a las 18:30