公告

微信

欢迎大家私信交流

Skip to content

IO

什么是IO

计算机的写入,输出。 简称读写。

数据是通过IO总线进行流动,数据在磁盘和内存之间流动,称之为磁盘IO,数据在网络和内存之间流动,称之为网络IO。

IO包

主要接口:读、写、关、寻

io.Reader

go
type Reader interface {
 Read(p []byte) (n int, err error)
}

io.Reader表示一个读取器,它将数据从某个资源读取到传输缓冲区。

  • 入参:字节切片p
    • 会将数据读入到 p 中
  • 返回值:本次读取的字节数n,以及遇到的错误err

只要实现了Read方法 ,那它就是一个读取器

读字符串

go
// ioRead
func main() {
 // string.NewReader(string) -> 创建一个字符串读取器
 reader := strings.NewReader("cy handsome")
 num := 0
 all := make([]byte, 0)
 for {
  // 分片读取
  p := make([]byte, 4)
  // 通过方法 定义返回值
  n, err := reader.Read(p)
  // 读完没有错误 会传一个io.EOF
  if err != nil {
   if err == io.EOF {
    fmt.Println("读取完成")
    log.Printf("读取的的字节数:%d和内容:%v \n", num, string(all[:num]))
    break
   }
   log.Fatalf("读取错误:%v \n", err)
  }
  num += n
  // 每个整数代表一个 ASCII 码值
  all = append(all, p...)
 }
 fmt.Println(all)
}

读取文件

go
func main() {
 readFile("./1.txt")
}

func readFile(path string) {
 file, err := os.Open(path)
 if err != nil {
  log.Fatal(err)
 }

 //注意关闭文件流
 defer func(file *os.File) {
  err := file.Close()
  if err != nil {
   log.Fatal(err)
  }
 }(file)

 // 缓存片
 buff := make([]byte, 1024)

 // 无限循环
 for {
  n, err := file.Read(buff)
  if err != nil {
   if err == io.EOF {
    fmt.Println("读完了")
    break
   }
   log.Fatal(err)
  }
  fmt.Printf("读取到的内容:%v \n ", string(buff[:n]))
 }
}

io.Writer

go
type Writer interface {
    //Write() 方法有两个返回值,一个是写入到目标资源的字节数,一个是发生错误时的错误。
    Write(p []byte) (n int, err error)
}

io.Writer 表示一个写入器,它从缓冲区读取数据,并将数据写入目标资源。

只要实现了 Write(p []byte) ,那它就是一个写入器。

go
// 写覆盖
func writeFile(content string) {
 // 新建文件
 file, err := os.Create("./2.txt")
 if err != nil {
  fmt.Println(err)
  return
 }
 defer file.Close()
 _, err = file.Write([]byte(content))
 if err != nil {
  return
 }
}

io.Seeker

go
type Seeker interface {
 //用于指定下次读取或者写入时的偏移量
 // 入参:起始值、基于起始值的偏移量
 // 返回值:基于whence和offset计算的新偏移量和可能产生的错误
 Seek(offset int64, whence int) (int64, error)
}
const (
 SeekStart   = 0 // 基于文件开始位置
 SeekCurrent = 1 // 基于当前偏移量 
 SeekEnd     = 2 // 基于文件结束位置
)

func writeFile(content string) {
 // 打开文件 
 // 参数2:打开模式
 // 参数3:权限控制
 // w写 r读 x执行   w  2   r  4   x  1
 // 特殊权限位,拥有者位,同组用户位,其余用户位
 file, err := os.OpenFile("./test.txt", os.O_RDWR, 655)
 if err != nil {
  fmt.Println(err)
  return
 }
 defer file.Close()
 _, err = file.Seek(4, io.SeekStart)
 if err != nil {
  log.Fatal(err)
 }
 _, err = file.Write([]byte(content))
 if err != nil {
  log.Fatal(err)
 }
}
  • os.O_WRONLY 只写
  • os.O_CREATE 创建文件
  • os.O_RDONLY 只读
  • os.O_RDWR 读写
  • os.O_TRUNC 清空
  • os.O_APPEND 追加

文件操作api

go
// 根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666
 func Create(name string) (file *File, err Error)

// 根据文件描述符创建相应的文件,返回一个文件对象
 func NewFile(fd uintptr, name string) *File

// 只读方式打开一个名称为name的文件
 func Open(name string) (file *File, err Error)

// 打开名称为name的文件,flag是打开的方式,只读、读写等,perm是权限
 func OpenFile(name string, flag int, perm uint32) (file *File, err Error)

// 写入byte类型的信息到文件
 func (file *File) Write(b []byte) (n int, err Error)

// 在指定位置开始写入byte类型的信息
 func (file *File) WriteAt(b []byte, off int64) (n int, err Error)

// 写入string信息到文件
 func (file *File) WriteString(s string) (ret int, err Error)

// 读取数据到b中
 func (file *File) Read(b []byte) (n int, err Error)

// 从off开始读取数据到b中
 func (file *File) ReadAt(b []byte, off int64) (n int, err Error)

// 删除文件名为name的文件
 func Remove(name string) Error

bufio

  • bufio.Reader:代表一个带缓冲的读取器,允许从输入流中按行或字节块读取数据。
  • bufio.Writer:代表一个带缓冲的写入器,允许将数据写入输出流并控制何时执行实际的写入操作。

bufio 适用于需要高效读写的场景

go
func wr() {
    file, err := os.OpenFile("./xxx.txt", os.O_CREATE|os.O_WRONLY, 0666)
    if err != nil {
        return
    }
    defer file.Close()
    // 获取writer对象
    writer := bufio.NewWriter(file)
    for i := 0; i < 10; i++ {
        writer.WriteString("hello\n")
    }
    // 刷新缓冲区,强制写出
    writer.Flush()
}

func re() {
    file, err := os.Open("./xxx.txt")
    if err != nil {
        return
    }
    defer file.Close()
    reader := bufio.NewReader(file)
    for {
        line, _, err := reader.ReadLine()
        if err == io.EOF {
            break
        }
        if err != nil {
            return
        }
        fmt.Println(string(line))
    }

}

ioutil

工具包

部分使用函数 ReadAll(从某个源读取数据)、ReadFile(读取文件内容)、WriteFile(将数据写入文件)、ReadDir(获取目录)

上次更新于: