最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang逐行讀取文件的操作

 更新時間:2020年12月22日 10:18:39   作者:思維的深度  
這篇文章主要介紹了golang逐行讀取文件的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

我就廢話不多說了,大家還是直接看代碼吧~

func ReadLine(fileName string) ([]string,error){
	f, err := os.Open(fileName)
	if err != nil {
		return nil,err
	}
	buf := bufio.NewReader(f)
	var result []string
	for {
		line, err := buf.ReadString('\n')
		line = strings.TrimSpace(line)
		if err != nil {
			if err == io.EOF { //讀取結(jié)束,會報EOF
				return result,nil
			}
			return nil,err
		}
		result = append(result,line)
	}
	return result,nil
}

補(bǔ)充:Golang讀取文件和處理超大文件方案

Golang 操作文件的讀取的方法很多,適用的場景也是各不相同,在此我們將文件的讀取分為如下幾種 :

文件整體讀取

文件分片讀取(塊級讀取)

文件行級讀取

系統(tǒng)的配置不同,執(zhí)行的耗時也不相同,此處給出一參考

系統(tǒng)配置 :

OS : Windows10

Memory : 16G

CPU (英特爾)Intel® Core™ i3-4370 CPU @ 3.80GHz(3800 MHz)

1. 文件整體讀取

文件整體讀取就是將文件一次性讀取到,理解上是將文件的內(nèi)容第一次就讀取完了

使用場景 :

針對小文件比較合適(大文件讀取空間和時間的消耗也很大)

對于整體性強(qiáng)的文件也比較合適(文件也不能太大)

代碼示例1

package main
import (
 "bufio"
 "fmt"
 "io"
 "io/ioutil"
 "log"
 "os"
 "time"
)
// 測試用的文本文件11M大小
var m11 string = `G:\runtime\log\ccapi\11M.log`
// 測試用的文本文件400M大小
var m400 string = `G:\runtime\log\ccapi\400M.log`

// 將整個文件都讀取
func readAll(filePath string) {
 start1 := time.Now()
 ioutil.ReadFile(filePath)
 fmt.Println("readAll spend : ", time.Now().Sub(start1))
}
func main() {
 readAll(m11)
 readAll(m400)
}

$ go run main.go
readAll spend : 6.9999ms
readAll spend : 358.8014ms

代碼示例2

package main
import (
 "bufio"
 "fmt"
 "io"
 "io/ioutil"
 "log"
 "os"
 "time"
)
// 測試用的文本文件11M大小
var m11 string = `G:\runtime\log\ccapi\11M.log`
// 測試用的文本文件400M大小
var m400 string = `G:\runtime\log\ccapi\400M.log`
// 將文件完整讀取
func readAllBuff(filePath string) {
 start1 := time.Now()
 // 打開文件
 FileHandle, err := os.Open(filePath)
 if err != nil {
 log.Println(err)
 return
 }
 // 關(guān)閉文件
 defer FileHandle.Close()
 // 獲取文件當(dāng)前信息
 fileInfo, err := FileHandle.Stat()
 if err != nil {
 log.Println(err)
 return
 }
 buffer := make([]byte, fileInfo.Size())
 // 讀取文件內(nèi)容,并寫入buffer中
 n, err := FileHandle.Read(buffer)
 if err != nil {
 log.Println(err)
 }
 // 打印所有切片中的內(nèi)容
 fmt.Println(string(buffer[:n]))
 fmt.Println("readAllBuff spend : ", time.Now().Sub(start1))
}
func main() {
 readAllBuff(m11)
 readAllBuff(m400)
}

2. 文件分片讀取

對文件一部分一部分逐步的讀取,直到文件完全讀取完

PS : 每次讀取文件的大小是根據(jù)設(shè)置的 分片 大小 ,所以對于讀取文本類型的文件時(例如 : 日志文件)

不一定是按照你的期望逐行輸出,因?yàn)椴粫幚砦谋疚膊康膿Q行符,而是按照分片大小讀取內(nèi)容

使用場景 :

讀取超大的文件很合適

讀二進(jìn)制類型的文件很合適(比如:音視頻文件或者資源類型文件等)

代碼示例

package main
import (
 "bufio"
 "fmt"
 "io"
 "io/ioutil"
 "log"
 "os"
 "time"
)
// 測試用的文本文件11M大小
var m11 string = `G:\runtime\log\ccapi\11M.log`
// 測試用的文本文件400M大小
var m400 string = `G:\runtime\log\ccapi\400M.log`
// 文件一塊一塊的讀取
func readBlock(filePath string) {
 start1 := time.Now()
 FileHandle, err := os.Open(filePath)
 if err != nil {
 log.Println(err)
 return
 }
 defer FileHandle.Close()
 // 設(shè)置每次讀取字節(jié)數(shù)
 buffer := make([]byte, 1024)
 for {
 n, err := FileHandle.Read(buffer)
 // 控制條件,根據(jù)實(shí)際調(diào)整
 if err != nil && err != io.EOF {
 log.Println(err)
 }
 if n == 0 {
 break
 }
 // 如下代碼打印出每次讀取的文件塊(字節(jié)數(shù))
 //fmt.Println(string(buffer[:n]))
 }
 fmt.Println("readBolck spend : ", time.Now().Sub(start1))
}
func main() {
 readBlock(m11)
 readBlock(m400)
}

$ go run main.go
readBolck spend : 31.9814ms
readBolck spend : 1.0889488s

3. 文件逐行讀取

對文件一行一行的讀取,直到讀到文件末尾

使用場景 :

讀取超大的文件很合適(例如 : 超大log文件等)

讀取的文件最好是有換行的(如果使用單行文件組成的大文件,需要注意)

對需要分析內(nèi)容的大文件

統(tǒng)計某些數(shù)據(jù)出現(xiàn)的次數(shù)

查詢某些數(shù)據(jù)是否存在

查找指定行的數(shù)據(jù)

示例代碼1

package main
import (
 "bufio"
 "fmt"
 "io"
 "io/ioutil"
 "log"
 "os"
 "time"
)
// 測試用的文本文件11M大小
var m11 string = `G:\runtime\log\ccapi\11M.log`
// 測試用的文本文件400M大小
var m400 string = `G:\runtime\log\ccapi\400M.log`
// 讀取文件的每一行
func readEachLineReader(filePath string) {
 start1 := time.Now()
 FileHandle, err := os.Open(filePath)
 if err != nil {
 log.Println(err)
 return
 }
 defer FileHandle.Close()
 lineReader := bufio.NewReader(FileHandle)
 for {
  // 相同使用場景下可以采用的方法
 // func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
 // func (b *Reader) ReadBytes(delim byte) (line []byte, err error)
 // func (b *Reader) ReadString(delim byte) (line string, err error)
 line, _, err := lineReader.ReadLine()
 if err == io.EOF {
 break
 }
 // 如下是某些業(yè)務(wù)邏輯操作
 // 如下代碼打印每次讀取的文件行內(nèi)容
 fmt.Println(string(line))
 }
 fmt.Println("readEachLineReader spend : ", time.Now().Sub(start1))
}
func main(){
 readEachLineReader(m11)
 readEachLineReader(m400)
}

$ go run main.go
readEachLineReader spend : 16.9902ms
readEachLineReader spend : 537.9683ms

代碼示例2

package main
import (
 "bufio"
 "fmt"
 "io"
 "io/ioutil"
 "log"
 "os"
 "time"
)
// 測試用的文本文件11M大小
var m11 string = `G:\runtime\log\ccapi\11M.log`
// 測試用的文本文件400M大小
var m400 string = `G:\runtime\log\ccapi\400M.log`
// 讀取文件的每一行
func readEachLineScanner(filePath string) {
 start1 := time.Now()
 FileHandle, err := os.Open(filePath)
 if err != nil {
 log.Println(err)
 return
 }
 defer FileHandle.Close()
 lineScanner := bufio.NewScanner(FileHandle)
 for lineScanner.Scan() {
  // 相同使用場景下可以使用如下方法
 // func (s *Scanner) Bytes() []byte
 // func (s *Scanner) Text() string
 // 實(shí)際邏輯 : 對讀取的內(nèi)容進(jìn)行某些業(yè)務(wù)操作
 // 如下代碼打印每次讀取的文件行內(nèi)容
 fmt.Println(lineScanner.Text())
 }
 fmt.Println("readEachLineScanner spend : ", time.Now().Sub(start1))
}
func main() {
 readEachLineScanner(m11)
 readEachLineScanner(m400)
}

$ go run main.go
readEachLineScanner spend : 17.9895ms
readEachLineScanner spend : 574.1722ms

4. 總結(jié)

面試中常見的類似超大文件讀取的問題,通常我們采用分片讀取或者逐行讀取的方案即可

大文件的上傳也可以采用類似的解決方案 , 每次讀取文件的部分內(nèi)容上傳(寫入)網(wǎng)絡(luò)接口中,直至文件讀取完畢

普通的小文件并且對內(nèi)容沒有太多操作的,可以采用整體讀取,速度相對較快

對文件內(nèi)容有操作的采用分片讀取和逐行讀取更合適

二進(jìn)制類型文件采用分片讀取或者整體讀取的方案比較合適

文件讀取不僅是本地文件,要讀去網(wǎng)絡(luò)上的文件(各種文檔,音視頻,圖片,和其他各種類型文件)時要訪問到文件獲取 io.ReadCloser 或者 io.Reader 后可以采用三種方式將文件內(nèi)容讀取到

func ReadAll(r io.Reader) ([]byte, error) 文件完整讀取

func Copy(dst Writer, src Reader) (written int64, err error) 文件讀取并寫入

type Reader interface {
 Read(p []byte) (n int, err error)
}

通過Reader 接口的 Read 方法讀取

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • golang使用http client發(fā)起get和post請求示例

    golang使用http client發(fā)起get和post請求示例

    這篇文章主要介紹了golang使用http client發(fā)起get和post請求示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Go語言命令行操作命令詳細(xì)介紹

    Go語言命令行操作命令詳細(xì)介紹

    這篇文章主要介紹了Go語言命令行操作命令詳細(xì)介紹,本文重點(diǎn)介紹了go build、go clean、go fmt、go get等命令,需要的朋友可以參考下
    2014-10-10
  • go-zero自定義中間件的幾種方式

    go-zero自定義中間件的幾種方式

    首先 go-zero 已經(jīng)為我們提供了很多的中間件的實(shí)現(xiàn),但有時難免有需求需要自定義,這里介紹幾種自定義的方法,文中通過代碼示例講解的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下
    2024-07-07
  • golang?使用chromedp獲取頁面請求日志network

    golang?使用chromedp獲取頁面請求日志network

    這篇文章主要為大家介紹了golang?使用chromedp獲取頁面請求日志network方法實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • sublime安裝支持go和html的插件

    sublime安裝支持go和html的插件

    這篇文章主要介紹了sublime安裝支持go和html的插件,需要的朋友可以參考下
    2015-01-01
  • 詳解Golang time包中的結(jié)構(gòu)體time.Ticker

    詳解Golang time包中的結(jié)構(gòu)體time.Ticker

    在日常開發(fā)過程中,會頻繁遇到對時間進(jìn)行操作的場景,使用 Golang 中的 time 包可以很方便地實(shí)現(xiàn)對時間的相關(guān)操作,接下來的幾篇文章會詳細(xì)講解 time 包,本文講解一下 time 包中的結(jié)構(gòu)體 time.Ticker,需要的朋友可以參考下
    2023-08-08
  • 基于Go和PHP語言實(shí)現(xiàn)爬樓梯算法的思路詳解

    基于Go和PHP語言實(shí)現(xiàn)爬樓梯算法的思路詳解

    這篇文章主要介紹了Go和PHP 實(shí)現(xiàn)爬樓梯算法,本文通過動態(tài)規(guī)劃和斐波那契數(shù)列兩種解決思路給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • golang中set數(shù)據(jù)結(jié)構(gòu)的使用示例

    golang中set數(shù)據(jù)結(jié)構(gòu)的使用示例

    本文主要介紹了golang中set數(shù)據(jù)結(jié)構(gòu)的使用示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • golang中日期操作之日期格式化及日期轉(zhuǎn)換

    golang中日期操作之日期格式化及日期轉(zhuǎn)換

    在編程中,程序員會經(jīng)常使用到日期相關(guān)操作,下面這篇文章主要給大家介紹了關(guān)于golang中日期操作之日期格式化及日期轉(zhuǎn)換的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • 使用Golang打印特定的日期時間的操作

    使用Golang打印特定的日期時間的操作

    這篇文章主要給大家詳細(xì)介紹了如何使用Golang打印特定的日期時間的操作,文中有詳細(xì)的代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-07-07

最新評論

云龙县| 景谷| 丰县| 济源市| 德昌县| 谢通门县| 长丰县| 仙桃市| 墨脱县| 吴旗县| 涿鹿县| 蓝山县| 阿合奇县| 谷城县| 北票市| 栾川县| 石家庄市| 东乌珠穆沁旗| 丘北县| 淄博市| 运城市| 滨海县| 上思县| 赤水市| 高州市| 江永县| 老河口市| 石阡县| 临湘市| 延吉市| 嘉荫县| 江达县| 东光县| 留坝县| 福清市| SHOW| 喀什市| 青海省| 德保县| 大名县| 新乡市|