zip.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package assist
  2. import (
  3. baseZip "archive/zip"
  4. "io"
  5. "os"
  6. )
  7. // ZipCompress 压缩文件
  8. // files 文件数组,可以是不同dir下的文件或者文件夹
  9. // dest 压缩文件存放地址
  10. func ZipCompress(files []*os.File, dest string) error {
  11. // 创建压缩文件
  12. d, _ := os.Create(dest)
  13. defer d.Close()
  14. // NewWriter创建并返回一个将zip文件写入w的*Writer。
  15. w := baseZip.NewWriter(d)
  16. defer w.Close()
  17. for _, file := range files {
  18. err := compress(file, "", w)
  19. if err != nil {
  20. return err
  21. }
  22. }
  23. return nil
  24. }
  25. func compress(file *os.File, prefix string, zw *baseZip.Writer) error {
  26. info, err := file.Stat()
  27. if err != nil {
  28. return err
  29. }
  30. if info.IsDir() {
  31. if len(prefix) == 0 {
  32. prefix = info.Name()
  33. } else {
  34. prefix = prefix + "/" + info.Name()
  35. }
  36. fileInfos, err := file.Readdir(-1)
  37. if err != nil {
  38. return err
  39. }
  40. for _, fi := range fileInfos {
  41. f, err := os.Open(file.Name() + "/" + fi.Name())
  42. if err != nil {
  43. return err
  44. }
  45. err = compress(f, prefix, zw)
  46. if err != nil {
  47. return err
  48. }
  49. }
  50. } else {
  51. // FileInfoHeader返回一个根据fi填写了部分字段的Header。
  52. header, err := baseZip.FileInfoHeader(info)
  53. if len(prefix) != 0 {
  54. header.Name = prefix + "/" + header.Name
  55. }
  56. if err != nil {
  57. return err
  58. }
  59. // 使用给出的*FileHeader来作为文件的元数据添加一个文件进zip文件。
  60. writer, err := zw.CreateHeader(header)
  61. if err != nil {
  62. return err
  63. }
  64. // 将文件复制到目标
  65. _, err = io.Copy(writer, file)
  66. file.Close()
  67. if err != nil {
  68. return err
  69. }
  70. }
  71. return nil
  72. }