package io

func Copy(dst Writer, src Reader) (written int64, err error)
将src的数据拷贝到dst,直到在src上到达EOF或发生错误。返回拷贝的字节数和遇到的第一个错误。
对成功的调用,返回值err为nil而非EOF,因为Copy定义为从src读取直到EOF,它不会将读取到EOF视为应报告的错误。
如果src实现了WriterTo接口,本函数会调用src.WriteTo(dst)进行拷贝;
否则如果dst实现了ReaderFrom接口,本函数会调用dst.ReadFrom(src)进行拷贝。

需求

将一张图片拷贝到另外一个目录下

代码实现

  1. // 拷贝文件
  2. package main
  3. import (
  4. "bufio"
  5. "fmt"
  6. "io"
  7. "os"
  8. )
  9. // 编写拷贝文件或者目录的函数
  10. func CopyFile(dstFileName string, srcFileName string) (written int64, err error) {
  11. // func Copy(dst Writer, src Reader) (written int64, err error)
  12. // 需要实现一个 Writer 和一个 Reader
  13. // 1、 先读取源文件,得到一个 Reader
  14. var reader *bufio.Reader
  15. var writer *bufio.Writer
  16. srcFile, err := os.Open(srcFileName)
  17. if err != nil {
  18. fmt.Printf("Open file: %v error: %v \n", srcFileName, err)
  19. } else {
  20. reader = bufio.NewReader(srcFile)
  21. // reader 类型: *bufio.Reader,
  22. fmt.Printf("reader 类型: %T, 值: %v \n", reader, reader)
  23. }
  24. defer srcFile.Close()
  25. // 2、打开 dstFileName ,得到一个 Writer
  26. dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY|os.O_CREATE, 0666)
  27. if err != nil {
  28. fmt.Printf("Open file: %v error: %v \n", dstFileName, err)
  29. } else {
  30. writer = bufio.NewWriter(dstFile)
  31. // writer 类型: *bufio.Writer,
  32. fmt.Printf("writer 类型: %T, 值: %v \n", writer, writer)
  33. }
  34. defer dstFile.Close()
  35. // 3、传入 Reader Writer , 调用 os.Copy(), 并返回
  36. return io.Copy(writer, reader)
  37. }
  38. func main() {
  39. filepath01 := "C:/Users/xiao/Pictures/iphone/baby.jpg"
  40. filepath02 := "C:/Users/xiao/Pictures/iphone/01.jpg"
  41. // 将 filepath02 拷贝到 filepath01, 并命名为 01.jpg
  42. _, err := CopyFile(filepath02, filepath01)
  43. if err != nil {
  44. fmt.Println("拷贝失败", err)
  45. } else {
  46. fmt.Println("拷贝成功")
  47. }
  48. }

代码解读

主要就是实现一个 Writer 和一个 Reader
io.Copy() 内部实现是带缓存的,读一点写一点,可以拷贝大文件

吐槽

Golang 为什么就没有一些语法糖呢,函数式编程🤔