2009-12-08 14 views
10

Es gibt eine Datei, die ich sicherstellen möchte, dass sie nicht größer als 2 GB wird (da sie auf einem System laufen muss, das ext 2 verwendet). Wie kann man die Größe einer Datei überprüfen, wenn man bedenkt, dass ich zwischen den Überprüfungen in diese Datei schreiben werde? Muss ich mich insbesondere über gepufferte, nicht abgeschlossene Änderungen Gedanken machen, die noch nicht auf die Festplatte geschrieben wurden?Wie ermittle ich die Größe einer geöffneten Datei in Python?

+2

Gibt es einen Grund können Sie nicht nur verfolgen, die Dateigröße selbst - das heißt, sehen, was die Größe ist, wenn Sie es öffnen und einen Zähler erhöhen, wenn Sie schreiben ?Nicht besonders elegant, aber es sollte funktionieren. –

+0

Ich vermute, das ist eine Möglichkeit, an die ich nicht gedacht hätte ... Ich könnte das auch versuchen. –

+0

Ist das nicht ineffizient als Hölle? –

Antwort

4

Sie mit so etwas wie dies beginnen könnte:

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) 

Dann könnten Sie es wie folgt verwendet werden:

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

Offensichtlich ist diese Umsetzung funktioniert nicht, wenn Sie die Datei nicht zu schreiben sind, von Grund auf, aber Sie könnten Ihre __init__ Methode anpassen, um anfängliche Daten zu behandeln. Sie müssen möglicherweise auch einige andere Methoden überschreiben: writelines, zum Beispiel.

Dies funktioniert unabhängig von der Codierung, da Strings nur Sequenzen von Bytes sind.

>>> 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: Das ist eine wirklich clevere Idee. Ich mag das! – jathanism

+0

Das ist nicht wirklich. Wenn Sie ASCII, ISO1559 und UTF-8 verwenden, wird das Ergebnis gleich sein, aber die Diskgröße wird nicht sein. –

+0

Nein. Es funktioniert auch für andere Codierungen, wenn Sie tatsächliche Zeichenfolgen verwenden. Antwort geändert, um zu demonstrieren. – jcdyer

15

Vielleicht nicht, was Sie wollen, aber ich werde es trotzdem vorschlagen.

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

Alternativ zu einer geöffneten Datei können Sie die fstat Funktion verwenden, die auf einer geöffneten Datei verwendet werden kann. Es dauert eine ganze Datei-Handle, nicht ein Dateiobjekt, so müssen Sie die fileno Methode auf dem Dateiobjekt verwenden:

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

Zuverlässigstes eine Verpackungsklasse schaffen würde, die Datei die Größe überprüfen würde, wenn Sie es öffnen, Verfolgen Sie Schreib- und Suchvorgänge, zählen Sie die aktuelle Größe basierend auf diesen Vorgängen und verhindern Sie, dass die Größenbeschränkung überschritten wird.

2

Oder, wenn die Datei bereits geöffnet ist:

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

Das ist, wie viele Bytes die Datei.

6

os.fstat(file_obj.fileno()).st_size sollte den Trick tun. Ich denke, dass es die geschriebenen Bytes zurückgibt. Sie können immer einen Flush vor der Hand machen, wenn Sie sich Gedanken über die Pufferung machen.

+0

Und funktioniert auch im Append-Modus! Vielen Dank. Und ja, ich würde spülen bevor ich das anrufe. –

4

Ich bin nicht vertraut mit Python, aber hat das Stream-Objekt (oder was auch immer Sie beim Öffnen einer Datei bekommen) eine Eigenschaft, die die aktuelle Position des Streams enthält?

Ähnlich wie Sie mit der ftell() C-Funktion oder Stream.Position in .NET erhalten.

Offensichtlich funktioniert das nur, wenn Sie am Ende des Streams positioniert sind, was Sie sind, wenn Sie gerade schreiben.

Der Vorteil dieses Ansatzes besteht darin, dass Sie die Datei nicht schließen müssen und sich nicht um nicht gelöschte Daten sorgen müssen.

+0

'filehandle.tell()' zeigt tatsächlich die Anzahl der Bytes in der geöffneten Datei an und funktioniert entweder im Schreib- oder im Anfügemodus. Nicht sicher, warum all diese komplexeren Antworten aufgewertet wurden. – hurfdurf

+1

@hurfdurf Nein, 'f.tell()' scheint im Append-Modus nicht zuverlässig zu funktionieren. Es sei denn du fängst zuerst (0,2) '. Ich habe keine Idee warum. –

4

Obwohl dies eine alte Frage ist, denke ich, dass Isak die einfachste Lösung hat. Hier ist, wie es in Python zu tun:

# 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

Ich denke, dass in der ersten Zeile (aktuelle Position speichern) sollten Sie f.tell(), nicht die seek(), die eine Ausnahme verursachen würde seit seek() benötigt mindestens 1 Argument. – Jkm

+0

@Jkm Ja, Sie haben Recht! Ich bin mir nicht sicher, wie ich das vermisst habe. Vielen Dank! – Trenton

+0

Dadurch wird die Dateigröße korrekt berechnet, die Position wird jedoch aufgrund bekannter Probleme mit [tell in append mode] (https://stackoverflow.com/questions/31680677/) nicht korrekt wiederhergestellt. –