Datei häppchenweise auslesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Twilo
User
Beiträge: 109
Registriert: Mittwoch 10. Januar 2007, 19:17
Wohnort: Berlin
Kontaktdaten:

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
[url=http://www.farb-tabelle.de/][b]Farbtabelle[/b][/url]
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

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.
tordmor
User
Beiträge: 100
Registriert: Donnerstag 20. November 2008, 10:29
Wohnort: Stuttgart

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.
http://www.felix-benner.com
Twilo
User
Beiträge: 109
Registriert: Mittwoch 10. Januar 2007, 19:17
Wohnort: Berlin
Kontaktdaten:

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 :wink:
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
[url=http://www.farb-tabelle.de/][b]Farbtabelle[/b][/url]
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

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.
Twilo
User
Beiträge: 109
Registriert: Mittwoch 10. Januar 2007, 19:17
Wohnort: Berlin
Kontaktdaten:

Hallo,

meinst du also, innerhalb meiner Klasse eine Methode get_content, welche das FooFile-Objekt zurück gibt?

mfg
Twilo
[url=http://www.farb-tabelle.de/][b]Farbtabelle[/b][/url]
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Ja.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Oder gar ein Property.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Twilo
User
Beiträge: 109
Registriert: Mittwoch 10. Januar 2007, 19:17
Wohnort: Berlin
Kontaktdaten:

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
[url=http://www.farb-tabelle.de/][b]Farbtabelle[/b][/url]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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

Code: Alles auswählen

buffer = buffer or len("12345678901234567890")
zu schreiben, das tut auch auf älteren Python-Versionen und ist kürzer.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Twilo
User
Beiträge: 109
Registriert: Mittwoch 10. Januar 2007, 19:17
Wohnort: Berlin
Kontaktdaten:

Hallo,

in php müßte es also:

Code: Alles auswählen

$buffer = &#40;$buffer === Null&#41; ? $buffer : strlen&#40;"12345678901234567890"&#41;; 
entsprechen

mfg
Twilo
[url=http://www.farb-tabelle.de/][b]Farbtabelle[/b][/url]
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Auch in PHP kann man OR benutzen:

Code: Alles auswählen

$buffer = $buffer || strlen&#40;"12345678901234567890"&#41;; 
Twilo
User
Beiträge: 109
Registriert: Mittwoch 10. Januar 2007, 19:17
Wohnort: Berlin
Kontaktdaten:

Hallo,
derdon hat geschrieben:Auch in PHP kann man OR benutzen:

Code: Alles auswählen

$buffer = $buffer || strlen&#40;"12345678901234567890"&#41;; 
das dürfte aber nur gehen, wenn buffer None/Null oder False ist

mfg
Twilo
[url=http://www.farb-tabelle.de/][b]Farbtabelle[/b][/url]
Antworten