Golang reading and writing files

Reading and writing files is one of the common operations of programming languages. Here, we will read the related operations of the files.

read file

There are three ways to read files:

  • Read the entire file into memory
  • Read by bytes
  • Read by line

The specific implementation is as follows:

1. Read the whole file into memory
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))
}

perhaps

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))
}

Read the whole file into memory, which is more efficient and occupies the most memory.

2. Read file by byte

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) //How many bytes are read at a time
   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))
}

or

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))
}

3. Read by line

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
         }
      }
   }

}

write file

There are the following write modes

1,ioutil.WriteFile

package main

import (
   "io/ioutil"
)

func main() {

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

In this way, the test.txt content will be overwritten every time. If the test.txt file does not exist, it will be created.

2,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 = "Test 1\n Test 2\n"
   var filename = "./test.txt"
   var f *os.File
   var err1 error
   if checkFileIsExist(filename) { //If the file exists
      f, err1 = os.OpenFile(filename, os.O_APPEND, 0666) //Open file
      fmt.Println("File exists")
   } else {
      f, err1 = os.Create(filename) //create a file
      fmt.Println("file does not exist")
   }
   defer f.Close()
   n, err1 := io.WriteString(f, wireteString) //Write file (string)
   if err1 != nil {
      panic(err1)
   }
   fmt.Printf("Write in %d Byte n", n)
}

This method adds new content at the end of the file content.

3,

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 = "Test 1\n Test 2\n"
   var filename = "./test.txt"
   var f *os.File
   var err1 error
   if checkFileIsExist(filename) { //If the file exists
      f, err1 = os.OpenFile(filename, os.O_APPEND, 0666) //Open file
      fmt.Println("File exists")
   } else {
      f, err1 = os.Create(filename) //create a file
      fmt.Println("file does not exist")
   }
   defer f.Close()
   n, err1 := f.Write([]byte(str)) //Write file (byte array)

   fmt.Printf("Write in %d Byte n", n)
   n, err1 = f.WriteString(str) //Write file (string)
   if err1 != nil {
      panic(err1)
   }
   fmt.Printf("Write in %d Byte n", n)
   f.Sync()
}

This method adds new content at the end of the file content.

4,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 = "Test 1\n Test 2\n"
   var filename = "./test.txt"
   var f *os.File
   var err1 error
   if checkFileIsExist(filename) { //If the file exists
      f, err1 = os.OpenFile(filename, os.O_APPEND, 0666) //Open file
      fmt.Println("File exists")
   } else {
      f, err1 = os.Create(filename) //create a file
      fmt.Println("file does not exist")
   }
   defer f.Close()
   if err1 != nil {
      panic(err1)
   }
   w := bufio.NewWriter(f) //Create a new Writer object
   n, _ := w.WriteString(str)
   fmt.Printf("Write in %d Byte n", n)
   w.Flush()
}

This method adds new content at the end of the file content.

Compare the efficiency of several read files

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) //How many bytes are read at a time
   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))

}

Operation result:

For the first time

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

The second time

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

Third time

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

links

Tags: Go Programming

Posted on Wed, 04 Dec 2019 09:05:10 -0500 by lmninfo