python:生成器經典應用(讀取只有一行500G檔案)
阿新 • • 發佈:2018-11-19
首先講解下場景 。
有一個檔案 大概有500G,並且只有一行,行之間有分隔符,我們需要把檔案內的資料一行一行的讀取出來,
然後寫入資料庫裡面。
有的小夥伴就報名說了,我們取行可以用open,然後用for迴圈。
看我的
with open(“file”)as f:
for i in f.readlines():
print i
由於它只有一行,你這樣讀取會把所有資料讀取出來,500G記憶體誰也承受不了
,這是沒有辦法做到的。
注意 這句話 行之間有分隔符 ,這就是咱們的切入點 。
首先解釋一個函式 file.read()
1.這個read 函式並不是一次讀取所有,可以傳入 int 引數,代表讀取的字元數
2.連續呼叫,可以讀取偏移量的值 。
有了這個我們的問題就迎刃而解。
例子如下:
file_phth="C:/Users/PycharmProjects/test1/test.txt"
with open(file_phth,"r") as f:
a=f.read(20)
b=f.read(20)
print(a,b)
列印結果:
Ten ,wang
i lov e you , tu ran hao
如果有這個函式,我們就可以做到讀取大資料。看下邊我編寫好的例子:
file_phth="C:/Users//PycharmProjects/test1/test.txt" def Myread(f,newline): bug="" #暫存讀取的而資料 while True: while newline in bug: #判斷 分隔符是否在暫存資料 pos=bug.index(newline) #用了index 方法並且返回分隔符的下標 yield bug[:pos] #取分隔符前面的值儲存在生成器 bug=bug[pos+len(newline):] # 取過值也更新bug,刪除前面取的值加上分隔符 chunk=f.read(200) #一次200個字元 if not chunk: #如果取不到值了,就用這個結束迴圈 yield bug #最後一個分隔符後邊的值也儲存在生成器裡 break bug=bug+chunk #200字元裡最後一個分隔符後邊的值 加上再次取到的chunk值 with open(file_phth,"r") as f: for i in Myread(f, newline="{|}"): print(i)
我先解釋下 工作流,這個是經典的例子並且配合的完美。
其中while 迴圈 是指取到的 200字元裡最後一個分隔符後邊的值 加上再次取到的chunk值 不停的遍歷
直到把所有的分隔符前面的值取完畢。
if 語句的用意 是:
當chunk 取不到值,也就是檔案內容的邊界了,要結束迴圈,並把最後一個分隔符後邊的值 再次yield。
最後一個for迴圈 遍歷生成器的值,取到的值直接可以插入資料庫。
思路:遇到超大檔案,不能直接放在記憶體中,要分段進行讀取 以減少記憶體的佔用
`