2016-06-04 13 views
1

Ich habe eine geteilte Datei (können sagen name.a0, name.a1, name.a2, ...)Treat separate Dateien als eine Datei-Objekt in Python

Gibt es eine Möglichkeit ein lesbares File- haben wie Objekt, das wird eine Verkettung von diesen sein, ohne eine temporäre Datei zu verwenden und ohne sie alle in den Speicher zu laden?

+0

Was beabsichtigen Sie zu tun, wenn die zugrunde liegenden Dateien geändert werden (und vor allem, wenn sie die Größe ändern)? Wenn Sie zum Beispiel halbwegs 'name.a1' sind und' name.a0' größer wird, sollte das Objekt automatisch seinen Offset anpassen, um sicherzustellen, dass Sie sich noch in der Mitte von 'name.a1' befinden? – Kevin

+0

ist mir egal. sie werden sich in meinem Fall nicht ändern –

Antwort

0

Sie können immer ein Proxy-Objekt erstellen, das eine Reihe von Dateien als eine behandelt. Sie müssen nur genug von file object interface implementieren, um die Anforderungen Ihres Programms zu erfüllen.

Zum Beispiel, wenn alles, was Sie tun Iterierte über die Zeilen in all diesen Dateien ist, das folgende Objekt würde für Python genügen 2:

class MultiFile(object): 
    def __init__(self, *filenames, mode='r'): 
     self._filenames = reversed(filenames) # reversed iterable 
     self._mode = mode 
     sef._openfile = open(next(self._filenames), self._mode) 

    def __enter__(self): 
     return self 

    def __exit__(self, *exception_info): 
     self._openfile.close() 

    __del__ = __exit__ 

    def __iter__(self): 
     return self 

    def __next__(self): 
     try: 
      return next(self._openfile) 
     except StopIteration: 
      # find next file to yield from, raises StopIteration 
      # when self._filenames has run out 
      while True: 
       self._opefile.close() 
       self._openfile = next(self._filenames) 
       try: 
        return next(self._openfile, self._mode) 
       except StopIteration: 
        continue 

Auf diese Weise können Sie eine Serie durchlesen von Dateien, als ob es war einer, Leselinien, wie Sie (so nie alles in den Speicher) gehen:

import glob 

for line in MultiFile(glob.glob('name.a?')): 
    # ... 

Beachten Sie, dass in Python 3 (oder wenn er io library in Python 2 verwenden) werden Sie eine der entsprechendenimplementieren müssenfür den Dateimodus (Raw, gepuffert oder Text).

+0

Vielen Dank für Ihre Antwort. Ich weiß, dass ich so etwas selbst implementieren kann, aber ich habe nach einer integrierten Implementierung gesucht. –

+0

@BugaleBugalit: Wie Sie bemerken, behandelt 'fileinput' nur die Iteration (aufeinanderfolgende' file.readline() 'Aufrufe). Wenn Sie Binärdateien mit 'file.read()' Aufrufen lesen müssen, gibt es keine Implementierung in der Standardbibliothek. –

3

Das Modul fileinput in der Python-Standardbibliothek wird genau für diesen Zweck verwendet.

import fileinput 
with fileinput.input(files=('name.a0', 'name.a1', 'name.a2')) as f: 
    for line in f: 
     process(line) 
+0

Ick, wie könnte ich 'fileinput' vergessen. Dieses Modul erstellt im Wesentlichen einen Proxy, wie ich es in meiner Antwort beschrieben habe. –

+0

Es sieht gut aus, aber es gibt ein Problem. Meine Dateien sind binäre Dateien und keine Textdateien, und es scheint, dass fileinput nur Lesezeilen implementiert, und nicht alle Funktionen einer Datei –

+0

Verwenden von 'mode = 'br'' funktioniert nicht? – SethMMorton

Verwandte Themen