Golang 讀、寫文件

文件的讀寫是編程語言的常見操做之一,這裏講一些Goang 讀取文件的相關操做。git

讀取文件

讀取文件有三種方式:github

  • 將文件整個讀入內存
  • 按字節數讀取
  • 按行讀取

具體實現以下:golang

一、將文件整個讀入內存
package main

import (
   "os"
   "io/ioutil"
   "fmt"
)

func main() {
   file, err := os.Open("D:/gopath/src/golang_development_notes/example/log.txt")
   if err != nil {
      panic(err)
   }
   defer file.Close()
   content, err := ioutil.ReadAll(file)
   fmt.Println(string(content))
}

或者編程

package main

import (
   "os"
   "io/ioutil"
   "fmt"
)

func main() {
   filepath := "D:/gopath/src/golang_development_notes/example/log.txt"
   content ,err :=ioutil.ReadFile(filepath)
   if err !=nil {
      panic(err)
   }
   fmt.Println(string(content))
}

將文件整個讀入內存,效率比較高,佔用內存也最高。數組

二、按字節讀取文件app

package main

import (
   "bufio"
   "fmt"
   "io"
   "io/ioutil"
   "os"
)

func main() {
   filepath := "D:/gopath/src/golang_development_notes/example/log.txt"
   fi, err := os.Open(filepath)
   if err != nil {
      panic(err)
   }
   defer fi.Close()
   r := bufio.NewReader(fi)

   chunks := make([]byte, 0)
   buf := make([]byte, 1024) //一次讀取多少個字節
   for {
      n, err := r.Read(buf)
      if err != nil && err != io.EOF {
         panic(err)
      }
      fmt.Println(string(buf[:n]))
      break
      if 0 == n {
         break
      }
      chunks = append(chunks, buf[:n]...)
   }
   fmt.Println(string(chunks))
}

編程語言

package main

import (
   "fmt"
   "io"
   "os"
)

func main() {

   file := "D:/gopath/src/golang_development_notes/example/log.txt"
   f, err := os.Open(file)
   if err != nil {
      panic(err)
   }
   defer f.Close()

   chunks := make([]byte, 0)
   buf := make([]byte, 1024)
   for {
      n, err := f.Read(buf)
      if err != nil && err != io.EOF {
         panic(err)
      }
      if 0 == n {
         break
      }
      chunks = append(chunks, buf[:n]...)
   }
   fmt.Println(string(chunks))
}

三、按行讀取測試

package main

import (
   "bufio"
   "fmt"
   "io"
   "io/ioutil"
   "os"
   "strings"
)

func main() {
   filepath := "D:/gopath/src/golang_development_notes/example/log.txt"
   file, err := os.OpenFile(filepath, os.O_RDWR, 0666)
   if err != nil {
      fmt.Println("Open file error!", err)
      return
   }
   defer file.Close()

   stat, err := file.Stat()
   if err != nil {
      panic(err)
   }
   var size = stat.Size()
   fmt.Println("file size=", size)

   buf := bufio.NewReader(file)
   for {
      line, err := buf.ReadString('\n')
      line = strings.TrimSpace(line)
      fmt.Println(line)
      if err != nil {
         if err == io.EOF {
            fmt.Println("File read ok!")
            break
         } else {
            fmt.Println("Read file error!", err)
            return
         }
      }
   }

}

寫入文件

有如下寫入方式code

一、ioutil.WriteFile對象

package main

import (
   "io/ioutil"
)

func main() {

   content := []byte("測試1\n測試2\n")
   err := ioutil.WriteFile("test.txt", content, 0644)
   if err != nil {
      panic(err)
   }
}

這種方式每次都會覆蓋 test.txt內容,若是test.txt文件不存在會建立。

二、os

package main

import (
   "fmt"
   "io"
   "os"
)

func checkFileIsExist(filename string) bool {
   if _, err := os.Stat(filename); os.IsNotExist(err) {
      return false
   }
   return true
}
func main() {
   var wireteString = "測試1\n測試2\n"
   var filename = "./test.txt"
   var f *os.File
   var err1 error
   if checkFileIsExist(filename) { //若是文件存在
      f, err1 = os.OpenFile(filename, os.O_APPEND, 0666) //打開文件
      fmt.Println("文件存在")
   } else {
      f, err1 = os.Create(filename) //建立文件
      fmt.Println("文件不存在")
   }
   defer f.Close()
   n, err1 := io.WriteString(f, wireteString) //寫入文件(字符串)
   if err1 != nil {
      panic(err1)
   }
   fmt.Printf("寫入 %d 個字節n", n)
}

此種方法能夠在文件內容末尾添加新內容。

三、

package main

import (
   "fmt"
   "os"
)

func checkFileIsExist(filename string) bool {
   if _, err := os.Stat(filename); os.IsNotExist(err) {
      return false
   }
   return true
}
func main() {
   var str = "測試1\n測試2\n"
   var filename = "./test.txt"
   var f *os.File
   var err1 error
   if checkFileIsExist(filename) { //若是文件存在
      f, err1 = os.OpenFile(filename, os.O_APPEND, 0666) //打開文件
      fmt.Println("文件存在")
   } else {
      f, err1 = os.Create(filename) //建立文件
      fmt.Println("文件不存在")
   }
   defer f.Close()
   n, err1 := f.Write([]byte(str)) //寫入文件(字節數組)

   fmt.Printf("寫入 %d 個字節n", n)
   n, err1 = f.WriteString(str) //寫入文件(字符串)
   if err1 != nil {
      panic(err1)
   }
   fmt.Printf("寫入 %d 個字節n", n)
   f.Sync()
}

此種方法能夠在文件內容末尾添加新內容。

四、bufio

package main

import (
   "bufio"
   "fmt"
   "os"
)

func checkFileIsExist(filename string) bool {
   if _, err := os.Stat(filename); os.IsNotExist(err) {
      return false
   }
   return true
}
func main() {
   var str = "測試1\n測試2\n"
   var filename = "./test.txt"
   var f *os.File
   var err1 error
   if checkFileIsExist(filename) { //若是文件存在
      f, err1 = os.OpenFile(filename, os.O_APPEND, 0666) //打開文件
      fmt.Println("文件存在")
   } else {
      f, err1 = os.Create(filename) //建立文件
      fmt.Println("文件不存在")
   }
   defer f.Close()
   if err1 != nil {
      panic(err1)
   }
   w := bufio.NewWriter(f) //建立新的 Writer 對象
   n, _ := w.WriteString(str)
   fmt.Printf("寫入 %d 個字節n", n)
   w.Flush()
}

此種方法能夠在文件內容末尾添加新內容。

對比幾種讀取文件效率

package main

import (
   "bufio"
   "fmt"
   "io"
   "io/ioutil"
   "os"
   "time"
)

func read0(path string) string {
   file, err := os.Open(path)
   if err != nil {
      panic(err)
   }
   defer file.Close()
   content, err := ioutil.ReadAll(file)
   return string(content)
}

func read1(path string) string {
   content, err := ioutil.ReadFile(path)
   if err != nil {
      panic(err)
   }
   return string(content)
}

func read2(path string) string {
   fi, err := os.Open(path)
   if err != nil {
      panic(err)
   }
   defer fi.Close()
   r := bufio.NewReader(fi)

   chunks := make([]byte, 0)
   buf := make([]byte, 1024) //一次讀取多少個字節
   for {
      n, err := r.Read(buf)
      if err != nil && err != io.EOF {
         panic(err)
      }
      if 0 == n {
         break
      }
      chunks = append(chunks, buf[:n]...)
   }
   return string(chunks)
}

func read3(path string) string {
   fi, err := os.Open(path)
   if err != nil {
      panic(err)
   }
   defer fi.Close()

   chunks := make([]byte, 0)
   buf := make([]byte, 1024)
   for {
      n, err := fi.Read(buf)
      if err != nil && err != io.EOF {
         panic(err)
      }
      if 0 == n {
         break
      }
      chunks = append(chunks, buf[:n]...)
   }
   return string(chunks)
}

func main() {

   file := "D:/gopath/src/example/example/log.txt"

   start := time.Now()

   read0(file)
   t0 := time.Now()
   fmt.Printf("Cost time %v\n", t0.Sub(start))

   read1(file)
   t1 := time.Now()
   fmt.Printf("Cost time %v\n", t1.Sub(t0))

   read2(file)
   t2 := time.Now()
   fmt.Printf("Cost time %v\n", t2.Sub(t1))

   read3(file)
   t3 := time.Now()
   fmt.Printf("Cost time %v\n", t3.Sub(t2))

}

運行結果:

第一次

Cost time 6.0003ms
Cost time 3.0002ms
Cost time 7.0004ms
Cost time 11.0006ms

第二次

Cost time 7.0004ms
Cost time 4.0003ms
Cost time 6.0003ms
Cost time 8.0005ms

第三次

Cost time 9.0006ms
Cost time 3.0001ms
Cost time 7.0004ms
Cost time 11.0007ms

links

相關文章
相關標籤/搜索