2009-12-08 19 views
10

Hay un archivo que me gustaría asegurar que no crezca más de 2 GB (ya que debe ejecutarse en un sistema que usa ext 2). ¿Cuál es una buena manera de verificar el tamaño de un archivo teniendo en cuenta que escribiré en este archivo entre revisiones? En particular, ¿debo preocuparme por los cambios almacenados en búfer que aún no se han escrito en el disco?¿Cómo determino el tamaño de un archivo abierto en Python?

+2

¿Hay alguna razón no se puede simplemente hacer un seguimiento del tamaño del archivo sí mismo - es decir, ver lo que el tamaño es cuando se abre y incrementar un contador cuando se escribe ?No es particularmente elegante, pero debería funcionar. –

+0

Supongo que es una posibilidad en la que no había pensado ... Podría intentar eso también. –

+0

¿No es eso tan ineficiente como el infierno? –

Respuesta

4

Se podría empezar con algo como esto:

class TrackedFile(file): 
    def __init__(self, filename, mode): 
     self.size = 0 
     super(TrackedFile, self).__init__(filename, mode) 
    def write(self, s): 
     self.size += len(s) 
     super(TrackedFile, self).write(s) 

entonces se podría utilizar de esta manera:

>>> f = TrackedFile('palindrome.txt', 'w') 
>>> f.size 
0 
>>> f.write('A man a plan a canal ') 
>>> f.size 
21 
>>> f.write('Panama') 
27 

Obviamente, esta aplicación no funciona si no está escribiendo el archivo desde cero, pero podría adaptar su método __init__ para manejar los datos iniciales. Es posible que también deba sobrescribir algunos otros métodos: writelines, por ejemplo.

Esto funciona independientemente de la codificación, ya que las cadenas son solo secuencias de bytes.

>>> f2 = TrackedFile('palindrome-latin1.txt', 'w') 
>>> f2.write(u'A man a plan a canál '.encode('latin1') 
>>> f3 = TrackedFile('palindrome-utf8.txt', 'w') 
>>> f3.write(u'A man a plan a canál '.encode('utf-8')) 
>>> f2.size 
21 
>>> f3.size 
22 
+0

+1: Esa es una idea realmente inteligente. ¡Me gusta! – jathanism

+0

Eso no es en realidad. Si usa ASCII, ISO1559 y UTF-8, el resultado será el mismo, pero el tamaño del disco no lo será. –

+0

No. Funciona para otras codificaciones también, si usa cadenas reales. Respuesta modificada para demostrar. – jcdyer

15

Quizás no sea lo que quiere, pero lo sugeriré de todos modos.

import os 
a = os.path.getsize("C:/TestFolder/Input/1.avi") 

alternativa para un archivo abierto se puede utilizar la función fstat, que puede ser utilizado en un archivo abierto. Se necesita un identificador de archivo entero, no un objeto de archivo, así que hay que utilizar el método fileno en el objeto de archivo:

a = open("C:/TestFolder/Input/1.avi") 
b = os.fstat(a.fileno()).st_size 
2

más fiable sería crear una clase envoltorio que comprobar el tamaño del archivo cuando se abre, realizar un seguimiento de las operaciones de escritura y búsqueda, contar el tamaño actual en función de esas operaciones y evitar exceder el límite de tamaño.

2

O bien, si el archivo ya está abierto:

>>> fsock = open('/etc/hosts', 'rb').read() 
>>> len(fsock) 
444 

Esa es la cantidad de bytes del archivo es.

6

os.fstat(file_obj.fileno()).st_size deberían hacer el truco. Creo que devolverá los bytes escritos. Siempre puede hacer un color antes de la mano si le preocupa el almacenamiento en búfer.

+0

¡Y funciona también en el modo de adición! Gracias. Y sí, me sonrojaría antes de llamar a esto. –

4

No estoy familiarizado con Python, pero ¿el objeto de transmisión (o lo que se obtiene al abrir un archivo) tiene una propiedad que contiene la posición actual de la secuencia?

Similar a lo que obtienes con la función ftell() C, o Stream.Position en .NET.

Obviamente, esto solo funciona si se encuentra al final de la secuencia, que es usted si actualmente está escribiendo en ella.

El beneficio de este enfoque es que no tiene que cerrar el archivo o preocuparse por los datos no eliminados.

+0

'filehandle.tell()' de hecho muestra el número de bytes en el archivo abierto, y funciona en modo de escritura o de adición. No estoy seguro de por qué todas estas respuestas más complejas se subieron. – hurfdurf

+1

@hurfdurf No, 'f.tell()' no parece funcionar de manera confiable en el modo de adición. A menos que primero 'f.seek (0,2)'. No tengo ni idea de porqué. –

4

Aunque esta es una vieja pregunta, creo que Isak tiene la solución más simple. Así es como hacerlo en Python:

# Assuming f is an open file 
>>> pos = f.tell() # Save the current position 
>>> f.seek(0, 2) # Seek to the end of the file 
>>> length = f.tell() # The current position is the length 
>>> f.seek(pos) # Return to the saved position 
>>> print length 
1024 
+0

Creo que en la primera línea (guardar la posición actual), debe usar f.tell(), no seek(), lo que causaría una excepción ya que seek() necesita al menos 1 argumento. – Jkm

+0

@Jkm Sí, tienes razón! No estoy seguro de cómo me perdí eso. ¡Gracias! – Trenton

+0

Esto calculará correctamente el tamaño del archivo, pero no restaurará la posición correctamente debido a problemas conocidos con [tell in append mode] (https://stackoverflow.com/questions/31680677/). –

Cuestiones relacionadas