2013-07-20 9 views
5

Sto cercando di recuperare un intero file in memoria (fatto - usando StringIO) - ma questi oggetti non si comportano esattamente esattamente come i "veri" file per quanto posso vedere - ottengo l'intero contenuto, o posso leggere una riga alla volta, ma non riesco a capire come applicare questo schema:Come ottenere un lettore CSV per leggere un file di memoria?

import csv 
with open(#MYMEMORYFILE_HERE#, 'rb') as csvfile: 
     spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|') 
     for row in spamreader: 

c'è un modo di trattare un memoryfile proprio come un file su disco, in modo da poter utilizzare gli idiomi più bello sopra ?

Python 2.7.4 (default, Apr 19 2013, 18:28:01) 

EDIT: Grazie per le risposte su questo - penso di avere ristretto ciò che mi era confusa ... ma ho ancora un problema qui, il seguente non visualizzerà nulla? Sospetto che il rossore?

from csv import reader, writer 
import StringIO 

memfile=StringIO.StringIO() 
spamwriter = writer(memfile) 
spamwriter.writerow(['Spam'] * 5 + ['Baked Beans']) 
spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam']) 
spamreader=reader(memfile) 
for row in spamreader: 
     print ', '.join(row) 
memfile.close() 

EDIT # 2: Ma sto abbaiare contro l'albero sbagliato penso: non ho potuto ottenere la versione su disco di questo lavoro sia ('IOError: File non aprire per la lettura' - quando Io chiamo la lettura sul file già aperto ...) EDIT # 3: abbandonato il StringIO (non ce n'è davvero bisogno) - usate le linee di divisione come da risposta.

Lascerò il codice e i commenti qui - nel caso sia utile. (anche se è un vicolo cieco).

+0

Anni dopo, vedo che hai aggiornato la tua domanda; il tuo aggiornamento fallisce perché ti sei dimenticato di * cercare di tornare a 0 *. –

risposta

9

Se si desidera leggere un intero file in memoria, ed è il testo, non c'è bisogno di aprire un oggetto StringIO. Basta leggerlo come una stringa!

with open(filename, 'r') as file: 
    in_memory_file = file.read() 

Quindi è possibile utilizzare splitlines per scorrere su di esso il modo in cui si iterare su un file di testo aperto.

spamreader = csv.reader(in_memory_file.splitlines(), delimiter=' ', quotechar='|') 
for row in spamreader: 
    pass 
+0

In realtà questo si adatta a quello che sto cercando di fare abbastanza bene (sto leggendo per prima cosa da un file su disco e copiando su file in memoria) - Darò questo risultato - grazie. – monojohnny

+0

Yup - fantastico - da quando sono passato da read() -> readlines() -> open idiom che ho dimenticato tutto sulle linee di divisione :) StringIO era eccessivo! Saluti – monojohnny

4

Non v'è alcuna necessità di aprire l'oggetto StringIO, è già un oggetto file aperto:

spamreader = csv.reader(MYMEMORYFILE_HERE, delimiter=' ', quotechar='|') 

Tutto ciò che csv.reader() esigenze è un oggetto iterabile. Un oggetto StringIO soddisfa questo requisito.

Demo:

>>> from StringIO import StringIO 
>>> data = StringIO('1,2,3\n4,5,6\n') 
>>> import csv 
>>> for row in csv.reader(data): 
...  print row 
... 
['1', '2', '3'] 
['4', '5', '6'] 

Per quanto riguarda il proprio StringIO.StringIO prova; hai scritto su un oggetto file ma hai trascurato di ricominciare da capo; nessun dato verrà letto come il puntatore del file è ancora alla fine. Seek indietro:

memfile.seek(0) 
spamreader=reader(memfile) 
Problemi correlati