13 votes

Après avoir écrit dans un fichier, pourquoi os.path.getsize renvoie-t-il toujours la taille précédente ?

J'essaie de diviser un grand fichier xml en petits morceaux. J'écris dans le fichier de sortie et je vérifie ensuite sa taille pour voir si elle dépasse un seuil, mais je ne pense pas que la méthode getsize() fonctionne comme prévu.

Quel serait un bon moyen d'obtenir la taille d'un fichier dont la taille change ?

J'ai fait quelque chose comme ça...

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

En exécutant ceci, la taille des fichiers est de 0 pendant environ 80 itérations, puis de 4176. Python stocke-t-il la sortie dans un tampon avant de l'afficher ?

11voto

Sriram Points 897

La taille du fichier est différente de la position du fichier. Par exemple,

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

Il renvoie exactement la taille du fichier en octets.

Mais

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

Ici, f.tell() renvoie la position actuelle du gestionnaire de fichiers - c'est-à-dire l'endroit où la prochaine écriture placera ses données. Puisqu'elle est consciente de la mise en mémoire tampon, elle devrait être précise tant que vous ne faites qu'ajouter des données au fichier de sortie.

10voto

RichieHindle Points 98544

Oui, Python met en mémoire tampon votre sortie. Vous feriez mieux de suivre la taille vous-même, quelque chose comme ceci :

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

(Cela peut ne pas être exact à 100 %, par exemple, sous Windows, chaque ligne gagnera un octet en raison de l'utilisation de la fonction \r\n séparateur de ligne, mais cela devrait être suffisant pour un simple chunking).

5voto

Piotr Czapla Points 8626

Avez-vous essayé de remplacer os.path.getsize par os.tell, comme ceci :

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

4voto

efotinis Points 6338

Le suivi de la taille par vous-même conviendra parfaitement à votre cas. Une autre solution serait de vider les tampons de fichiers juste avant de vérifier la taille :

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

Si vous le faites trop souvent, cela ralentira les entrées/sorties de fichiers, bien sûr.

1voto

Zv_oDD Points 421

Pour trouver le décalage vers la fin d'un fichier :

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

Exemple concret : lire les mises à jour d'un fichier et les imprimer au fur et à mesure :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X