golang讀取檔案總結
阿新 • • 發佈:2022-05-17
1. 讀取整個檔案
讀取整個檔案是效率最高的一種方式,但其只適用於小檔案,大檔案一次讀取會消耗大量記憶體
1.1 使用檔名直接讀取
使用os.ReadFile()
方法可以實現直接讀取
func fileOne() {
content, err := os.ReadFile("test.txt")
if err != nil {
panic(err)
}
fmt.Println(string(content))
}
使用ioutil.ReadFile()
方法可以實現一樣的效果,這兩個函式其實是完全一樣的
func fileTwo() { content, err := ioutil.ReadFile("test.txt") if err != nil { panic(err) } fmt.Println(string(content)) }
1.2 先建立檔案控制代碼再讀取檔案
如果想以只讀方式開啟檔案的話,可以直接使用os.Open()
方法
func fileThree() {
file, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer file.Close()
content, err := ioutil.ReadAll(file)
fmt.Println(string(content))
}
或者使用通用的os.OpenFile()
方法,不過要多加兩個引數
func fileFour() { file, err := os.OpenFile("test.txt", os.O_RDONLY, 0) if err != nil { panic(err) } defer file.Close() content, err := ioutil.ReadAll(file) fmt.Println(string(content)) }
2. 按行讀取
按行讀取主要使用ioutil
庫,其中有兩個方法可以實現按行讀取
但要注意的是,按行讀取是以'\n'
來區分每一行的,如果是沒有分行的大檔案,就不能使用按行讀取了
使用ioutil.ReadBytes()
實現按行讀取檔案
func fileFive() { // 建立檔案控制代碼 fi, err := os.Open("test.txt") if err != nil { panic(err) } defer fi.Close() // 建立reader r := bufio.NewReader(fi) for { lineBytes, err := r.ReadBytes('\n') line := strings.TrimSpace(string(lineBytes)) if err != nil && err != io.EOF { panic(err) } if err == io.EOF { break } fmt.Println(line) } }
使用ioutil.ReadString()
同樣可以實現按行讀取
func fileSix() {
// 建立檔案控制代碼
fi, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer fi.Close()
// 建立reader
r := bufio.NewReader(fi)
for {
line, err := r.ReadString('\n')
line = strings.TrimSpace(line)
if err != nil && err != io.EOF {
panic(err)
}
if err == io.EOF {
break
}
fmt.Println(line)
}
}
3. 按位元組數讀取
對於不分行的大檔案來說,只能使用按位元組讀取來讀取整個檔案
按位元組讀取可以使用os
庫或者syscall
庫來實現
使用os
庫實現按位元組讀取
func fileSeven() {
// 建立檔案控制代碼
fi, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer fi.Close()
// 建立reader
r := bufio.NewReader(fi)
// 每次讀取1024個位元組
buf := make([]byte, 1024)
for {
n, err := r.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
}
}
使用syscall
庫實現按位元組讀取
func fileEight() {
fd, err := syscall.Open("test.txt", syscall.O_RDONLY, 0)
if err != nil {
fmt.Println("Failed on open: ", err)
}
defer syscall.Close(fd)
var wg sync.WaitGroup
wg.Add(2)
dataChan := make(chan []byte)
go func() {
wg.Done()
for {
data := make([]byte, 100)
n, _ := syscall.Read(fd, data)
if n == 0 {
break
}
dataChan <- data
}
close(dataChan)
}()
go func() {
defer wg.Done()
for {
select {
case data, ok := <-dataChan:
if !ok {
return
}
fmt.Println(string(data))
default:
}
}
}()
wg.Wait()
}