1. 程式人生 > >python:生成器經典應用(讀取只有一行500G檔案)

python:生成器經典應用(讀取只有一行500G檔案)

首先講解下場景 。
有一個檔案 大概有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迴圈 遍歷生成器的值,取到的值直接可以插入資料庫。

思路:遇到超大檔案,不能直接放在記憶體中,要分段進行讀取 以減少記憶體的佔用

`