Golang 實現超大檔案讀取的兩種方法

2022-09-21 17:03:09 字數 3079 閱讀 1602

流處理方式

分片處理

去年的面試中我被問到超大檔案你怎麼處理,這個問題確實當時沒多想,回來之後仔細研究和討論了下這個問題,對大檔案讀取做了乙個分析

比如我們有乙個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...