打开和关闭文件

os.open 打开一个文件,返回一个 *File 和一个 err

file, err := os.Open("./main.go")

file.Close() 关闭文件资源,为了防止文件忘记关闭,我们通常使用 defer 注册文件关闭语句

file, err := os.Open("./main.go")
file.Close()

文件读取

os.Open会返回一个file指针,这个file指针有一个Read方法,可以把file里的内容读取到传入的切片参数里,并且返回读取的字节数和可能的具体错误,读到文件末尾时会返回 0io.EOF,一下例子,一次性读取指定大小的文件内容

func main() {
  file, err := os.Open("./readme.txt")
  defer file.Close()
  if err != nil {
     fmt.Println(err)
        return
  }

   // 读取128个直接,如果文件大小小于128字节,则读取实际的大小
  tmp := make([]byte, 128)
    n, err := file.Read(tmp)
    if err == io.EOF {
      fmt.Println("文件读完了")
      return
  } else if err != nil {
      fmt.Println(err)
        return
  }
   fmt.Println("读取了", n, "字节的数据")
  fmt.Println(string(tmp[:n])) // 字节切片转为字符串输出
}

可以使用for循环,读取文件的所有的内容

func main() {
   file, err := os.Open("./readme.txt")
  defer file.Close()
  if err != nil {
     fmt.Println(err)
        return
  }

   var content []byte
  // 一次读取128个字节,如果文件大小小于128字节,则读取实际的大小
    tmp := make([]byte, 128)
    for {
       _, err := file.Read(tmp) // 每次读取,都会被重新赋值
        if err == io.EOF {
          fmt.Println("文件读完了")
          break // 退出循环
       } else if err != nil {
          fmt.Println(err)
            return // 错误的话直接结束
      }
       content = append(content, tmp...)
   }

   fmt.Println(string(content)) // 字节切片转为字符串输出
}

我们还还可以使用bufio包的NewReader方法,bufio 是在 file 的基础上封装了一层 API,支持更多的功能,按行来读取文件指针的内容

func main() {
    file, err := os.Open("./readme.txt")
  defer file.Close()
  if err != nil {
     fmt.Println(err)
        return
  }

   reader := bufio.NewReader(file)
 for {
       line, err := reader.ReadString('\n') // 注意要用单引号
      if err == io.EOF {
          fmt.Println("文件读完了")
          break // 退出循环
       } else if err != nil {
          fmt.Println(err)
            return // 错误的话直接结束
      }
       fmt.Println(line)
   }
}

读取整个文件的内容,还有一个更加简单的方法,就是io/ioutil 包的 ReadFile 方法能够读取完整的文件,只需要将文件名作为参数传入

func main() {
  content, err := ioutil.ReadFile("./readme.txt")
   if err != nil {
     fmt.Println(err)
        return
  }

   fmt.Println(string(content)) // 可以将byte切片转字符串
}

文件写入

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,追加
func main() {
  file, err := os.OpenFile("new.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
 if err != nil {
     fmt.Println("打开文件错误:", err)
       return
  }
   defer file.Close()
  str := "hello world"

  file.Write([]byte(str))   // 切片的形式写入
    file.WriteString("你好,世界") // 字符串的形式写入
}

为了提高写入速度,可以用缓冲写入

func main() {
   file, err := os.OpenFile("new.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
 if err != nil {
     fmt.Println("打开文件错误:", err)
       return
  }
   defer file.Close()
  writer := bufio.NewWriter(file)
 writer.WriteString("你好,世界!")
  writer.Flush() // 要刷入磁盘
}

还可以使用ioutil.WriteFile 方式,直接写入

func main() {
  str := "你好,世界!"
   err := ioutil.WriteFile("./xx.txt", []byte(str), 0666)
    if err != nil {
     fmt.Println("err:", err)
  }
}
最后修改:2023 年 12 月 30 日
如果觉得我的文章对你有用,请随意赞赏