go 文件操作
IO包的基础使用 https://blog.csdn.net/elihe2011/article/details/124472104 Reader interface type Reader i
go 文件操作
发布时间:2023-10-06 (2023-10-06)

IO包的基础使用

https://blog.csdn.net/elihe2011/article/details/124472104

Reader interface

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

将len(p)个字节读取到p中

Writer interface

type Writer interface {
  Write(p []byte) (n int, err error)
}

用于将p中的数据写入到对象的数据流中

Seek interface

type Seeker interface {
  Seek(offset int64, whence int) (int64, error)
}

offset是指针移动的偏移量

whence表示指针移动的方式

0 从数据的头部开始移动指针

1 从数据的当前指针位置开始移动指针

2 从数据的尾部移动指针

seek设置下一次读写操作的指针位置,每次的读写操作都是从指针位置开始的

Close interface

type Closer interface {
  Close() error
}

关闭文件

文件操作

文件打开模块

O_RDONLY int = syscall.O_RDONLY // 只读
O_WRONLY int = syscall.O_WRONLY // 只写
O_RDWR   int = syscall.O_RDWR   // 读写
O_APPEND int = syscall.O_APPEND // 追加
O_CREATE int = syscall.O_CREAT  // 如果不存在就创建
O_EXCL   int = syscall.O_EXCL   // 文件必须不存在
O_SYNC   int = syscall.O_SYNC   // 同步io
O_TRUNC  int = syscall.O_TRUNC  // 打开时清空文件

读取文件

os.Open(name string) (file *File, err error)
ioutil.ReadFile(name string) ([]byte, error)
os.ReadFile(name string) ([]byte, error)
os.OpenFile(name string, flag int, perm FileMode) (*File, error)

一次性读

func main() {
  bs, err := os.ReadFile("./abc.txt")
  if err != nil {
    fmt.Printf("Read file error: %v\n", err)
    return
  }

  fmt.Printf("%s\n", bs)
}

分片读

func main() {
  file, err := os.Open("abc.txt")
  if err != nil {
    panic(err)
  }
  defer file.Close()

  for {
    buf := make([]byte, 32)
    _, err = file.Read(buf)
    if err == io.EOF {
      break
    }

    if err != nil {
      panic(err)
    }

    fmt.Printf("%s", buf)
  }
}

带缓冲读

func main() {
  file, err := os.Open("./abc.txt")
  if err != nil {
    fmt.Printf("Open file error: %v\n", err)
    return
  }
  defer file.Close()

  reader := bufio.NewReader(file)
  for {
    // 按行读取
    line, err := reader.ReadString('\n')
    if err == io.EOF {
      break
    }
    fmt.Print(line)
  }
}

光标操作

file, _ := os.Open("abc.txt")
defer file.Close()

// 开始位置前进5个字节
var whence = 0
var offset int64 = 5
pos, _ := file.Seek(offset, whence)
fmt.Println("Jump forward 5 bytes from start position:", pos)

// 当前位置回退2个字节
whence = 1
offset = -2
pos, _ = file.Seek(offset, whence)
fmt.Println("Jump back 2 bytes from current position:", pos)
}

分隔符读

func main() {
  file, _ := os.Open("abc.txt")
  defer file.Close()

  scanner := bufio.NewScanner(file)

  // 分隔函数,默认 bufio.ScanLines
  scanner.Split(bufio.ScanWords)

  for scanner.Scan() {
    fmt.Println(scanner.Text())
  }

  err := scanner.Err()
  if err != nil {
    panic(err)
  }
}

按行读

func main() {
  file, _ := os.Open("abc.txt")
  defer file.Close()

  scanner := bufio.NewScanner(file)

  // 分隔函数,默认 bufio.ScanLines
  scanner.Split(bufio.ScanWords)

  for scanner.Scan() {
    fmt.Println(scanner.Text())
  }

  err := scanner.Err()
  if err != nil {
    panic(err)
  }
}

写入文件

os.OpenFile(name string, flag int, perm FileMode) (file *File, err error)
os.Create(name string) (*File, error)
io/ioutil.Write(filename string, data []byte, perm fs.FileMode) error

文件操作模式:
覆盖写:os.O_WRONLY | os.O_TRUNC
追加写:os.O_WRONLY | os.O_APPEND
读写并追加:os.O_RDWR | os.OS_APPEND

常规写

func writeFile() {
  file, err := os.OpenFile("abc.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644)
  if err != nil {
    panic(err)
  }
  defer file.Close()

  byteSlice := []byte("hello world!")
  bytesWritten, err := file.Write(byteSlice)
  if err != nil {
    panic(err)
  }
  fmt.Printf("Wrote %d bytes\n", bytesWritten)
}

快速写

func main() {
  err := ioutil.WriteFile("abc.txt", []byte("add a new line"), 0644)
  if err != nil {
    panic(err)
  }
}

缓冲写

func main() {
  file, err := os.OpenFile("abc.txt", os.O_CREATE|os.O_WRONLY, 0600)
  if err != nil {
        panic(err)
  }
  defer file.Close()

  msg := "Hello World!\n"

  writer := bufio.NewWriter(file)
  for i := 0; i < 5; i++ {
    writer.Write([]byte(msg))
  }
  writer.Flush()
}

复制文件

io.Copy(dst Writer, src Reader) (written int64, err error)
read, _ := os.Open("xxx.jpg")
write, _ := os.Create("xx2.jpg")
n, err := io.Copy(write, read)
fmt.Println(n, err)

目录操作

递归展示文件夹下所有文件

func readDir(path string) {
  dir, err := os.ReadDir(path)
  if err != nil {
    fmt.Println(err)
    return
  }

  for _, entry := range dir {
    name := entry.Name()
    nPath := fmt.Sprintf("%s/%s", path, name)
    if entry.IsDir() {
      readDir(nPath)
      continue
    }
    fmt.Println(nPath)

  }
}