Seite 1 von 1
Datei häppchenweise auslesen
Verfasst: Samstag 4. April 2009, 13:40
von Twilo
Hallo,
ich möchte bzw. muss eine Datei häppchenweise auslesen
bei folgenden Codeausschnitt wird der komplette Dateiinhalt in die Variable content geschrieben; bei kleinen Dateien mag das zwar OK sein, bei Dateien die 400MB oder größer sind aber bestimmt nhicht mehr
Code: Alles auswählen
def get_file_length(self, path):
return int(svn.fs.svn_fs_file_length(self, fs_root, path))
def get_file_contens(self, path):
stream = svn.fs.svn_fs_file_contents(self, fs_root, path)
content = svn.core.svn_stream_read(stream, self.get_file_length())
svn.core.svn_stream_close(stream)
return content
wie kann bzw. muss ich die Methode get_file_contens ändern, damit ich immer eine buffer-Länge angebe, die mir zurückgegeben wird.
z.B.
get_file_contens('/trunk/a', 5) - gibt mir die ersten 5 Byte der Datei /trunk/a zurück
get_file_contens('/trunk/a', 5) - gibt mir die nächsten 5 Byte der Datei /trunk/a zurück
get_file_contens('/trunk/b', 5) - gibt mir die ersten 5 Byte der Datei /trunk/v zurück
get_file_contens('/trunk/a', 10) - gibt mir die nächsten 10 Byte der Datei /trunk/a zurück
get_file_contens('/trunk/a') - gibt mir die restlichen Bytes der Datei /trunk/a zurück
get_file_contens('/trunk/b') - gibt mir die restlichen Bytes der Datei /trunk/b zurück
das ganze müßte man dann auch pro Datei irgendwie neu starten können.
Twilo
Verfasst: Samstag 4. April 2009, 14:04
von DasIch
Es heißt content. fs_root sollte eine Konstante sein die man durchgehend groß schreiben würde oder ein Argument der Funktion get_file_contents
Dein Beispiel ist eine gewaltige Katastrophe, solche Seiteneffekte sind ziemlich böse.
Ich würde dir raten eine Klasse zu machen die sich wie eine Dateiobjekt verhält.
Verfasst: Samstag 4. April 2009, 17:00
von tordmor
Spontan hätte ich gesagt einen Generator erzeugen (yield) und in ein dictionary schreiben. Dann die neue Blockgröße mit send an den Generator schicken.
Verfasst: Samstag 4. April 2009, 19:40
von Twilo
Hallo,
DasIch hat geschrieben:Es heißt content. fs_root sollte eine Konstante sein die man durchgehend groß schreiben würde oder ein Argument der Funktion get_file_contents
Dein Beispiel ist eine gewaltige Katastrophe, solche Seiteneffekte sind ziemlich böse.
das ist kommt in einer Klasse, ich hatte jedoch vorher die grundsätzliche Funktionalität mit ipython getestet. Danach den Methodenrumpf nur noch davor geschrieben und dabei leider vergessen fs_root durch self._fs_root zu ersetzen.
die Methode soll später auch get_file_contents lauten.
Code: Alles auswählen
def get_file_length(self, path):
return int(svn.fs.svn_fs_file_length(self, self._fs_root, path))
def get_file_contents(self, path):
stream = svn.fs.svn_fs_file_contents(self, self._fs_root, path)
content = svn.core.svn_stream_read(stream, self.get_file_length())
svn.core.svn_stream_close(stream)
return content
jetzt sollte es passen
DasIch hat geschrieben:Ich würde dir raten eine Klasse zu machen die sich wie eine Dateiobjekt verhält.
wie meinst du das?
mfg
Twilo
Verfasst: Samstag 4. April 2009, 19:57
von DasIch
Statt diesen get_file_* Kram würde ich eine Klasse haben die z.B. so aussieht.
Code: Alles auswählen
class FooFile(object):
def __init__(self, fs_root, path):
self.fs_root, self.path = fs_root, path
def __len__(self):
return int(svn.fs.svn_fs_file_length(self, self.fs_root, self.path))
def read(self, buffer=None):
buffer = buffer is buffer is not None else len(self)
stream = svn.fs.svn_fs_file_contents(self, self.fs_root, self.path)
content = svn.core.svn_stream_read(stream, buffer)
svn.core.svn_stream_close(stream)
return content
Da buffer eine Funktion aus bultin ist, sollte man mit dem überschreiben allerdings aufpassen.
Verfasst: Sonntag 5. April 2009, 22:34
von Twilo
Hallo,
meinst du also, innerhalb meiner Klasse eine Methode get_content, welche das FooFile-Objekt zurück gibt?
mfg
Twilo
Verfasst: Sonntag 5. April 2009, 22:39
von DasIch
Ja.
Verfasst: Montag 6. April 2009, 08:39
von Leonidas
Oder gar ein Property.
Verfasst: Montag 6. April 2009, 11:42
von Twilo
Hallo,
DasIch hat geschrieben:Ja.
ok
Code: Alles auswählen
In [1]: buffer = 5
In [2]: buffer = buffer is buffer is not None else len("12345678901234567890")
------------------------------------------------------------
File "<ipython console>", line 1
buffer = buffer is buffer is not None else len("12345678901234567890")
^
<type 'exceptions.SyntaxError'>: invalid syntax
Code: Alles auswählen
buffer = buffer if buffer is not None else len("12345678901234567890")
ich tippe mal, dass das erste is ein if sein muss.
So eine Syntax habe ich bisher nicht verwendet; wie ist diese zu verstehen?
mfg
Twilo
Verfasst: Montag 6. April 2009, 11:48
von Leonidas
Twilo hat geschrieben:So eine Syntax habe ich bisher nicht verwendet; wie ist diese zu verstehen?

``wert-wenn-wahr`` if ``bedingung`` else ``wert-wenn-falsch``
Das gibt es aber erst seit Python 2.5.
Aber in dem Fall ists wohl einfacher
zu schreiben, das tut auch auf älteren Python-Versionen und ist kürzer.
Verfasst: Montag 6. April 2009, 12:13
von Twilo
Hallo,
in php müßte es also:
Code: Alles auswählen
$buffer = ($buffer === Null) ? $buffer : strlen("12345678901234567890");
entsprechen
mfg
Twilo
Verfasst: Montag 6. April 2009, 12:31
von derdon
Auch in PHP kann man OR benutzen:
Code: Alles auswählen
$buffer = $buffer || strlen("12345678901234567890");
Verfasst: Montag 6. April 2009, 13:01
von Twilo
Hallo,
derdon hat geschrieben:Auch in PHP kann man OR benutzen:
Code: Alles auswählen
$buffer = $buffer || strlen("12345678901234567890");
das dürfte aber nur gehen, wenn buffer None/Null oder False ist
mfg
Twilo