Golang学习笔记-文件读写操作

293 阅读3分钟

背景

学习笔记:利用Golang对文件进行读写操作

文件操作

一、读操作

  1. 设置缓冲区的读操作:默认4096缓冲区bufio.NewReader(),或者自定义缓冲区bufio.NewReaderSize(),适合读取大体量内容的文件。
package main

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

func main() {
   // 一个需要读取的txt文件
   filePath := "test.txt"
   file, err := os.Open(filePath)
   if err != nil {
      fmt.Println("error msg: ", err)
   }
   // 延时关闭文件,防止内存泄露
   defer func() {
      err := file.Close()
      if err != nil {
         fmt.Println("close file err: ", err)
         return
      }
   }()
   // 创建读取缓冲区,默认4096字节
   reader := bufio.NewReader(file)
   // 创建自定义读取缓冲区,设置2048字节
   // reader := bufio.NewReaderSize(file, 2048)
   // 循环读取文件内容
   for {
      content, err := reader.ReadString('\n')
      // 判断是否是文件末尾
      if err == io.EOF {
         break
      }
      fmt.Print(content)
   }
}
  1. 一次性全量读取操作,适合小体量内容的文件。其中ioutil.ReadFile()函数内封装了defer file.close(),所以在调用过程中无需再释放文件。
package main

import (
   "fmt"
   "io/ioutil"
)

func main() {
   // 一个需要读取的txt文件
   filePath := "test.txt"
   // 读取文件内容到内存中,值为[]byte类型
   content, err := ioutil.ReadFile(filePath)
   if err != nil {
      fmt.Println("read file error: ", err)
   }
   // []byte转string
   result := string(content)
   fmt.Println(result)
}
  1. 读取Json文件,创建一个结构体来反序列化Json文件中的内容。
package main

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

type Student struct {
   Id   int    `json:"id"`
   Name string `json:"name"`
   Age  int    `json:"age"`
}

func main() {
   // json文件的路径
   filePath := "test.json"
   jsonFile, err := os.Open(filePath)
   if err != nil {
      fmt.Println("open json file error: ", err)
   }
   // 延时关闭文件,防止内存泄露
   defer func() {
      err := jsonFile.Close()
      if err != nil {
         fmt.Println("close file error: ", err)
      }
   }()
   // 从文件中读取,直到出现错误或EOF,并返回读取的数据
   jsonData, err := ioutil.ReadAll(jsonFile)
   if err != nil {
      fmt.Println("read file error: ", err)
   }
   // 创建一个student对象
   var student Student
   // 利用Unmarshal反序列化数据到结构体
   err = json.Unmarshal(jsonData, &student)
   if err != nil {
      fmt.Println("unmarshal json error: ", err)
   }
   fmt.Println(student)
}

二、写操作

设置缓冲区的写操作:默认4096缓冲区bufio.NewWriter(),或者自定义缓冲区bufio.NewWriterSize()

package main

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

func main() {
   // 新文件的路径
   filePath := "test.txt"
   // 打开一个文件,只写操作,如果没有该文件则自动新增
   file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
   if err != nil {
      fmt.Println("open file error: ", err)
   }
   // 延时关闭文件,防止内存泄露
   defer func() {
      err := file.Close()
      if err != nil {
         fmt.Println("close file error: ", err)
      }
   }()
   // 需要写入的string
   newStr := "Hello World"
   // 使用默认带缓存的*Writer,默认4096字节
   writer := bufio.NewWriter(file)
   // 使用自定义缓存的*Writer,设置2048字节
   // writer := bufio.NewWriterSize(file, 2048)
   _, err = writer.WriteString(newStr)
   if err != nil {
      fmt.Println("write string error: ", err)
   }
   // 将缓存的内容刷新到文件中
   err = writer.Flush()
   if err != nil {
      fmt.Println("flush error: ", err)
   }
}

操作os.OpenFile()函数:

  • perm FileMode文件权限的选择
0777:-rwxrwxrwx,创建了一个普通文件,所有人拥有所有的读、写、执行权限
0666:-rw-rw-rw-,创建了一个普通文件,所有人拥有对该文件的读、写权限,但是都不可执行
0644:-rw-r--r--,创建了一个普通文件,文件所有者对该文件有读写权限,用户组和其他人只有读权限,没有执行权限
  • flag int模式的选择
os.O_RDONLY:    以只读的方式打开
os.O_WRONLY:    以只写的方式打开
os.O_RDWR :     以读写的方式打开
os.O_NONBLOCK:  打开时不阻塞
os.O_APPEND:    以追加的方式打开
os.O_CREAT:     创建并打开一个新文件
os.O_TRUNC:     打开一个文件并截断它的长度为零(必须有写权限)
os.O_EXCL:      如果指定的文件存在,返回错误
os.O_SHLOCK:    自动获取共享锁
os.O_EXLOCK:    自动获取独立锁
os.O_DIRECT:    消除或减少缓存效果
os.O_FSYNC :    同步写入
os.O_NOFOLLOW:  不追踪软链接
  • 几种常用模式
os.O_WRONLY | os.O_CREATE | O_EXCL      如果已经存在,则失败  
os.O_WRONLY | os.O_CREATE               如果已经存在,会覆盖写,不会清空原来的文件,而是从头直接覆盖写  
os.O_WRONLY | os.O_CREATE | os.O_APPEND 如果已经存在,则在尾部添加写