流處理方式
分片處理
去年的面試中我被問到超大檔案你怎麼處理,這個問題確實當時沒多想,回來之後仔細研究和討論了下這個問題,對大檔案讀取做了乙個分析
比如我們有乙個log檔案,執行了幾年,有100g之大。按照我們之前的操作可能**會這樣寫:
func readfile(filepath string) byte
return content
}上面的**讀取幾兆的檔案可以,但是如果大於你本身及其記憶體,那就直接翻車了。因為上面的**,是把檔案所有的內容全部都讀取到記憶體之後返回,幾兆的檔案,你記憶體夠大可以處理,但是一旦上幾百兆的檔案,就沒那麼好處理了。
那麼,正確的方法有兩種
func readfile(filepath string, handle func(string)) error
buf := bufio.newreader(f)
for
return err
}return nil}}
當讀取的是二進位制檔案,沒有換行符的時候,使用下面的方案一樣處理大檔案
func readbigfile(filename string, handle func(byte)) error
defer f.close()
s := make(byte, 4096)
for
1、我們取出 call_in_date": "2021-04-15 13:52:1的資料寫入另乙個檔案
*/ var (
s time.time //當前時間
file *os.file
filestat os.fileinfo
err error
lastlinesize int64
) s = time.now()
if file, err = os.open("/users/zhangsan/downloads/log.txt");err != nil
defer func() ()
//querystarttime, err := time.parse("2006-01-02t15:04:05.0000z", starttimearg)
//if err != nil
// //queryfinishtime, err := time.parse("2006-01-02t15:04:05.0000z", finishtimearg)
//if err != nil
/*** , sys:syscall.stat_t, atimespec:syscall.timespec,
mtimespec:syscall.timespec, ctimespec:syscall.timespec, birthtimespec:syscall.timespec,
size:911100961, blocks:1784104, blksize:4096, flags:0x0, gen:0x0, lspare:0, qspare:[2]int64}
* */
if filestat, err = file.stat();err != nil
filesize := filestat.size()//72849354767
offset := filesize - 1
//檢測是不是都是空行 只有\n
for
char = string(b[0])
if char == "\n"
offset--
//獲取一行的大小
lastlinesize += int64(n)
} var (
lastline byte
logslice string
logslice1 string
) //初始化一行大小的空間
lastline = make(byte, lastlinesize)
_, err = file.readat(lastline, offset)
if err != nil
//根據條件進行區分
logslice = strings.split(strings.trim(string(lastline),"\n"),"next_pay_date")
logslice1 = strings.split(logslice[1],"\"")
if logslice1[2] == "2021-06-15"
fmt.println("\ntime taken - ", time.since(s))
fmt.println(err)
}func process(f *os.file) error }
//讀取回來的資料池
stringpool := sync.pool }
//乙個檔案物件本身是實現了io.reader的 使用bufio.newreader去初始化乙個reader物件,存在buffer中的,讀取一次就會被清空
r := bufio.newreader(f) //
//設定讀取緩衝池大小 預設16
r = bufio.newreadersize(r,250 *1024)
var wg sync.waitgroup
for
if err == io.eof
return err
} //補齊剩下沒滿足的剩餘
nextuntillnewline, err := r.readbytes('\n')
if err != io.eof
wg.add(1)
go func() ()
} wg.wait()
return nil
}func processchunk(chunk byte, linespool *sync.pool,stringpool *sync.pool)
執行go run test2.go "2020-01-01t00:00:00.0000z" "2020-02-02t00:00:00.0000z" /users/zhangsan/go/src/workspace/test/log.log
eoftime taken - 20.023517675s
本文標題: golang 實現超大檔案讀取的兩種方法
本文位址:
php 讀取超大檔案
php開發很多時候都要讀取大檔案,比如csv檔案 text檔案等。這些檔案如果很大,比如10個g。這時,直接一次性把所有的內容讀取到記憶體中計算不太現實。遇到這種情況,往往覺得php太弱,實則不然。利用生成器 關鍵字yield 就能解決。好了,上 created by phpstorm.user a...
Python chunk讀取超大檔案
16gb小水存已經不能適應動輒4gb 8gb的資料檔案了。查詢到pandas的read csv 提供了chunk分塊讀取能力。這是一張原始的table in 185 table pd.read csv tmp.sv sep in 186 table out 186 unnamed 0 0 1 2 3...
php實現讀取超大檔案的方法
通常來說在php讀取大檔案的時候,我們採用的方法一般是一行行來講取,而不是一次性把檔案全部寫入記憶體中,這樣會導致php程式卡死,下面就給大家介紹這樣乙個例子。讀取大檔案最後幾行資料 取檔案最後 n行 param string filename 檔案路徑 param int n 最後幾行 retur...