2013-07-20 168 views
5

我試圖將整個文件讀入內存(完成 - 使用StringIO) - 但是,儘管我可以看到這些對象的行爲完全不像'真正'文件 - 我獲取了全部內容,或者我可以一次讀取一條線,但我不能工作,如何應用此模式:如何讓CSV閱讀器讀取內存文件?

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

是否有治療memoryfile就像磁盤上的文件的方式,所以我可以用更好的成語以上 ?

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

編輯:謝謝你對這個問題的答案 - 我想我已經收窄了什麼困惑我......但我仍然在這裏有一個問題,下面不輸出什麼?我懷疑沖洗?

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() 

編輯#2:但是我找錯了樹我想:我不能讓上盤版的這個工作是(「IO錯誤:文件無法打開閱讀」 - 當我打開已經打開的文件上的讀取...) 編輯#3:放棄了StringIO(沒有真正需要它) - 根據答案使用分裂線。

我會在這裏留下代碼和評論 - 以防萬一它有用。 (儘管它是一個死路)。

+0

年後,我看到你更新了你的問題;你的更新失敗,因爲你忘記*追回到0 *。 –

回答

9

如果你想閱讀整個文件到內存中,它的文字,你並不需要打開一個StringIO對象。只讀它作爲一個字符串!

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

然後你可以使用splitlines在它迭代,你會遍歷一個打開的文本文件的方式。

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

其實這符合我想要做的很好(我首先從磁盤文件中讀取並複製到內存文件中) - 我會放棄這一點 - 謝謝。 – monojohnny

+0

是的 - 很好 - 自從我使用read() - > readlines() - >打開成語後,我忘記了所有關於分裂線的知識:) StringIO太過分了!乾杯 – monojohnny

4

無需打開StringIO對象,它是已經一個打開的文件對象:

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

所有這一切csv.reader()需求是一個迭代的對象。 A StringIO物體符合該要求。

演示:

>>> 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'] 

至於自己StringIO.StringIO測試;你寫了一個文件對象,但忽略了回到起點;由於文件指針仍處於末尾,因此不會讀取任何數據。尋求回:

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