文件操作
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
2.0 KiB

3 years ago
3 years ago
3 years ago
  1. package file
  2. import (
  3. "errors"
  4. "io"
  5. "net/http"
  6. "os"
  7. "strconv"
  8. )
  9. /**
  10. * 文件是否存在
  11. */
  12. func IsFileExist(filename string, filesize int64) (bool, error) {
  13. info, err := os.Stat(filename)
  14. if os.IsNotExist(err) {
  15. return false, err
  16. }
  17. if filesize == info.Size() {
  18. // fmt.Println("已存在!", info.Name(), info.Size(), info.ModTime())
  19. return true, nil
  20. }
  21. err = os.Remove(filename)
  22. return false, err
  23. }
  24. /**
  25. * 文件下载
  26. * param url 要下载的文件URL
  27. * param localPath 文件保存路径或文件保存名称
  28. * fb 回调下载进度
  29. */
  30. func DownProgress(url string, localPath string, fb func(length, downLen int64)) error {
  31. var (
  32. fsize int64
  33. buf = make([]byte, 32*1024)
  34. written int64
  35. )
  36. tmpFilePath := localPath + ".download"
  37. //创建一个http client
  38. client := new(http.Client)
  39. //client.Timeout = time.Second * 60 //设置超时时间
  40. //get方法获取资源
  41. resp, err := client.Get(url)
  42. if err != nil {
  43. return err
  44. }
  45. //读取服务器返回的文件大小
  46. fsize, err = strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 32)
  47. if err != nil {
  48. // fmt.Println(err)
  49. }
  50. if ok, _ := IsFileExist(localPath, fsize); ok {
  51. return err
  52. }
  53. //创建文件
  54. file, err := os.Create(tmpFilePath)
  55. if err != nil {
  56. return err
  57. }
  58. defer file.Close()
  59. if resp.Body == nil {
  60. return errors.New("body is null")
  61. }
  62. defer resp.Body.Close()
  63. //下面是 io.copyBuffer() 的简化版本
  64. for {
  65. //读取bytes
  66. nr, er := resp.Body.Read(buf)
  67. if nr > 0 {
  68. //写入bytes
  69. nw, ew := file.Write(buf[0:nr])
  70. //数据长度大于0
  71. if nw > 0 {
  72. written += int64(nw)
  73. }
  74. //写入出错
  75. if ew != nil {
  76. err = ew
  77. break
  78. }
  79. //读取是数据长度不等于写入的数据长度
  80. if nr != nw {
  81. err = io.ErrShortWrite
  82. break
  83. }
  84. }
  85. if er != nil {
  86. if er != io.EOF {
  87. err = er
  88. }
  89. break
  90. }
  91. //没有错误了快使用 callback
  92. fb(fsize, written)
  93. }
  94. if err == nil {
  95. file.Close()
  96. err = os.Rename(tmpFilePath, localPath)
  97. }
  98. return err
  99. }