<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
// 全部讀取後按換行拆分 func ReadFile1(path string) error { fileHanle,err := os.OpenFile(path, os.O_RDONLY, 0666) if err != nil { return err } defer fileHanle.Close() readBytes, err := ioutil.ReadAll(fileHanle) if err != nil { return err } results := strings.Split(string(readBytes), "n") fmt.Printf("read result:%v", results) return nil }
實現方式:使用iouitl一次性讀取全部檔案內容,然後使用"n"進行分割成行。
這種實現最簡單,但是隻適合都內容比較小的檔案,當讀取大檔案的時候,一次讀到記憶體需要佔用比較大的記憶體。
func ReadFile2(path string) error { fileHanle,err := os.OpenFile(path, os.O_RDONLY, 0666) if err != nil { return err } defer fileHanle.Close() reader := bufio.NewReader(fileHanle) var results []string // 按行處理txt for { line, _, err := reader.ReadLine() if err == io.EOF { break } results = append(results, string(line)) } fmt.Printf("read result:%vn", results) return nil }
實現方式:使用NewReader建立bufio.Reader,迴圈呼叫Reader的ReadLine按行讀取,直接讀到檔案結束標記EOF。
bufio.Reader封裝了io, 並實現了緩衝I/O,同時它也實現了io.Reader的方法的Read方法。bufio緩衝區有預設大小是4K。
從ReadLine返回的文字不包括行尾(“rn”或“n”)。
如果一行大於快取,isPrefix 會被設定為 true,同時返回該行的開始部分(等於快取大小的部分)。該行剩餘的部分就會在下次呼叫的時候返回。當下次呼叫返回該行剩餘部分時,isPrefix 將會是 false 。
bufio.Reader的ReadLine最終呼叫的是ReadSlice方法,而ReadSlice返回的[]byte是指向Reader 中的buffer的一個slice,而不是copy一份返回,所以讀取的slice可能會被一下讀取操作重新,所以官方建議是使用ReadBytes和ReadString方法。
要注意是ReadBytes和ReadString返回的結果中包含傳入的界定符,如果最終結果不需要界定符的話需要自己處理。
bufio.Reader除了有ReadLine按行讀取外,他還封裝了按指定標記分割的方法。如下圖
func ReadFile3(path string) error { fileHanle,err := os.OpenFile(path, os.O_RDONLY, 0666) if err != nil { return err } defer fileHanle.Close() scanner := bufio.NewScanner(fileHanle) var results []string // 按行處理txt for scanner.Scan(){ lineTxt := strings.TrimSpace(scanner.Text()) if len(lineTxt) == 0 { continue } results = append(results, lineTxt) } fmt.Printf("read result:%vn", results) return nil }
實現方式:使用NewScanner建立bufio.Scanner,使用迴圈呼叫scanner的Scan判斷是否掃描到資料,然後通過scannner.Text()方法獲取到掃描的字串。
bufio.Scanner它底層封裝了io.Reader, 它的實現就跟Scanner名稱一樣,是一個按位元組流掃描的掃描器,當掃描到滿足Split函數條件的位元組資料後,就直接返回對應的掃描到的內容。
預設情況下,它64k行限制,如果想更大,可以自己通過Buffer函數進行設定。
Scanner預設提供了以下方法:
Scanner
型別具有 Split
函數,該函數接受 SplitFunc
函數來確定 Scanner
如何拆分給定的位元組片。預設的 SplitFunc
是 ScanLines
,它將返回文字的每一行,並刪除行尾標記。Split的函數定義如下:
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
我們可以自定義實現SpiteFunc來實現不同的拆分方式,比如我們可以使用bufio.ScanWords實現方式來按單詞拆分,如下:
func WordCounter(){ const input = "Now is the winter of our discontent,nMade glorious summer by this sun of York.n" scanner := bufio.NewScanner(strings.NewReader(input)) scanner.Split(bufio.ScanWords) count := 0 for scanner.Scan() { count++ } if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "reading input:", err) } fmt.Printf("%dn", count) }
我可以跟蹤到bufio包scan.go的檔案可以看到ScanWords的實現程式碼如下:
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) { // Skip leading spaces. start := 0 for width := 0; start < len(data); start += width { var r rune r, width = utf8.DecodeRune(data[start:]) if !isSpace(r) { break } } // Scan until space, marking end of word. for width, i := 0, start; i < len(data); i += width { var r rune r, width = utf8.DecodeRune(data[i:]) if isSpace(r) { return i + width, data[start:i], nil } } // If we're at EOF, we have a final, non-empty, non-terminated word. Return it. if atEOF && len(data) > start { return len(data), data[start:], nil } // Request more data. return start, nil, nil }
該函數簽名和SplitFunc定義實現一致。
到此這篇關於go按行讀取檔案的三種實現方式的文章就介紹到這了,更多相關go按行讀取檔案內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45