Go语言学习笔记,十八之文件读写

25.文件读写

1.文件打开和读

A.文件分类:文本和二进制文件

B.文件存取方式:随机存取和顺序存取

文件打开代码示例:

  1: package main
  2: 
  3: import (
  4:     "bufio"
  5:     "fmt"
  6:     "io"
  7:     "os"
  8: )
  9: 
 10: func main() {
 11:     //只读的方式打开
 12:     inputFile, err := os.Open("input.dat")
 13:     if err != nil {
 14:             fmt.Printf("open file err:%v\n", err)
 15:             return
 16:     }
 17:     defer inputFile.Close()
 18: }

读文件

file.Read和file.ReadAt.

读到文件末尾返回:io.EOF

读出整个文件代码示例

  1: package main
  2: 
  3: import (
  4:     "fmt"
  5:     "io"
  6:     "os"
  7: )
  8: 
  9: func main() {
 10:     //只读的方式打开
 11:     inputFile, err := os.Open(`D:\project\goland\files\wenjianduxie.go`)
 12:     //如果你文件在GOPath里面,可以用下面的路径
 13:     //inputFile, err := os.Open("./wenjianduxie.go")
 14:     if err != nil {
 15:             fmt.Printf("err=%v\n", err)
 16:             return
 17:     }
 18:     defer func() {
 19:             err := inputFile.Close()
 20:             if err != nil {
 21:                     fmt.Println("err1=", err)
 22:             }
 23:     }()
 24:     var buf [128]byte
 25:     var content []byte
 26:     for {
 27:             n, err := inputFile.Read(buf[:])
 28:             if err == io.EOF {
 29:                     // 代表文件读完了
 30:                     break
 31:             }
 32:             if err != nil {
 33:                     fmt.Println("err=", err)
 34:             }
 35:             fmt.Println("length:", n)
 36:             // 将一个切片追加到另一个切片
 37:             content = append(content, buf[:n]...)
 38:             fmt.Println("data:\n", string(content))
 39:     }
 40: }

bufio原理

由于文件读写相对内存读写性能较差,所以在读大文件时需要添加一层缓冲区,这就是bufio。

缺点:可能会丢失缓存的数据

  1: func main() {
  2:     inputFile, err := os.Open("input.dat")
  3:     if err != nil {
  4:             fmt.Println("err=", err)
  5:             return
  6:     }
  7: 
  8:     defer inputFile.Close()
  9:     inputReader := bufio.NewReader(inputFile)
 10:     for {
 11:             // 以换行符为分隔,一行一行打印出来。
 12:             inputString, readerError :=inputReader.ReadString("\n")
 13:             if readerError == io.EOF {
 14:                     return 
 15:             }
 16:             fmt.Printf("The input was : %s", inputString)
 17:     }
 18: }

ioutil直接读取整个文件

  1: func main() {
  2:     inputFile := "products.txt"
  3:     outputFile := "products_copy.txt"
  4:     buf, err := ioutil.ReadFile(inputFile)
  5:     if err != nil{
  6:             fmt.Fprintf(os.Stderr, "File Error:%s\n", err)
  7:             return
  8:     }
  9:     fmt.Printf("%s\n", string(buf))
 10: }

读取gzip压缩文件

  1: func main() {
  2:     zipfile := "Myfile.gz"
  3:     //open里面也可以写路径
  4:     fi, err1 := os.Open(zipfile)
  5:     if err1 != nil {
  6:             fmt.Fprintf(os.Stderr, "File Error:%s\n", err1)
  7:             os.Exit(1)
  8:     }
  9:     fz, err2 := gzip.NewReader(fi)
 10:     if err2 != nil {
 11:             fmt.Fprintf(os.Stderr,"File Error:%s\n", err2)
 12:             return
 13:     }
 14:     var r *bufio.Reader
 15:     r = bufio.NewReader(fz)
 16:     for {
 17:             line, err := r.ReadString('\n')
 18:             if err != nil {
 19:                     fmt.Println(“Done reading file”)
 20:                     os.Exit(0)
 21:             }
 22:             fmt.Println(line)
 23:     }
 24: }

2.文件写入

os.OpenFile("文件名",文件打开模式,权限控制)

文件打开模式:

1. os.O_WRONLY 只写

2. os.O_CREATE 创建文件

3. os.O_RDONLY 只读

4. os.O_RDWR 读写

5. os.O_TRUNC 清空

6. OS.O_APPEND 追加

ps:可以这样写: os.O_WRONLY|os.O_CREATE,顺序从左到右

权限控制:

r --> 004

w --> 002

x –> 001

api

  1: file.Write()
  2: file.WriteAt()
  3: file.WriteString()

bufio文件写入缓存区

  1: writer := bufio.NewWriter() // 开辟缓存区
  2: writer.WriteString() // 写入缓存区
  3: writer.Flush() // 刷新,从缓存区写入文件

ioutil写入整个文件

  1: inputFile := "旧文件"
  2: outputFile := "写入的新文件"
  3: buf, err := ioutil.ReadFile(inputFile)
  4: err = ioutil.WriteFile(outputFile, buf, 0x644)

3.defer原理图示

执行顺序从上到下

{返回值=x}

return x --

{RET指令}

{返回值=x}

defer原理 -- {运行defer语句}

{RET指令}