github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zfile/compress.go (about) 1 package zfile 2 3 import ( 4 "archive/tar" 5 "archive/zip" 6 "compress/gzip" 7 "io" 8 "os" 9 "path/filepath" 10 "strings" 11 ) 12 13 // GzCompress use gzip to compress to tar.gz 14 func GzCompress(currentPath, dest string) (err error) { 15 dest = RealPath(dest) 16 var d *os.File 17 d, err = os.Create(dest) 18 if err != nil { 19 return 20 } 21 defer d.Close() 22 gw := gzip.NewWriter(d) 23 defer gw.Close() 24 tw := tar.NewWriter(gw) 25 defer tw.Close() 26 currentPath = RealPath(currentPath, true) 27 err = walkFile(currentPath, dest, err, func(path string, info *os.FileInfo) error { 28 header, err := tar.FileInfoHeader(*info, "") 29 if err != nil { 30 return err 31 } 32 header.Name = strings.Replace(path, currentPath, "", -1) 33 err = tw.WriteHeader(header) 34 if err != nil { 35 return err 36 } 37 var file *os.File 38 file, err = os.Open(path) 39 if err != nil { 40 return err 41 } 42 _, err = io.Copy(tw, file) 43 file.Close() 44 return err 45 }) 46 return 47 } 48 49 func walkFile(currentPath string, dest string, err error, writer func(path string, info *os.FileInfo) error) error { 50 return filepath.Walk(currentPath, 51 func(path string, info os.FileInfo, err error) error { 52 path = RealPath(path) 53 if info == nil || err != nil { 54 return err 55 } 56 if info.IsDir() || path == dest { 57 return nil 58 } 59 60 return writer(path, &info) 61 }) 62 } 63 64 // GzDeCompress unzip tar.gz 65 func GzDeCompress(tarFile, dest string) error { 66 dest = RealPath(dest, true) 67 tarFile = RealPath(tarFile) 68 srcFile, err := os.Open(tarFile) 69 if err != nil { 70 return err 71 } 72 defer srcFile.Close() 73 gr, err := gzip.NewReader(srcFile) 74 if err != nil { 75 return err 76 } 77 defer gr.Close() 78 tr := tar.NewReader(gr) 79 for { 80 hdr, err := tr.Next() 81 if err != nil { 82 if err == io.EOF { 83 break 84 } else { 85 return err 86 } 87 } 88 i := hdr.FileInfo() 89 filename := dest + hdr.Name 90 if i.IsDir() { 91 _ = createDir(filename, i.Mode()) 92 } else { 93 file, err := createFile(filename) 94 if err != nil { 95 return err 96 } 97 _, err = io.Copy(file, tr) 98 _ = file.Close() 99 if err != nil { 100 return err 101 } 102 } 103 } 104 return nil 105 } 106 107 // ZipCompress zip 108 func ZipCompress(currentPath, dest string) (err error) { 109 dest = RealPath(dest) 110 var d *os.File 111 d, err = os.Create(dest) 112 if err != nil { 113 return 114 } 115 defer d.Close() 116 tw := zip.NewWriter(d) 117 defer tw.Close() 118 currentPath = RealPath(currentPath, true) 119 err = walkFile(currentPath, dest, err, func(path string, info *os.FileInfo) error { 120 header, err := zip.FileInfoHeader(*info) 121 if err != nil { 122 return err 123 } 124 header.Name = strings.Replace(path, currentPath, "", -1) 125 writer, err := tw.CreateHeader(header) 126 if err != nil { 127 return err 128 } 129 var file *os.File 130 file, err = os.Open(path) 131 if err != nil { 132 return err 133 } 134 _, err = io.Copy(writer, file) 135 _ = file.Close() 136 return err 137 }) 138 return err 139 } 140 141 func ZipDeCompress(zipFile, dest string) error { 142 dest = RealPath(dest, true) 143 zipFile = RealPath(zipFile) 144 reader, err := zip.OpenReader(zipFile) 145 if err != nil { 146 return err 147 } 148 defer reader.Close() 149 for _, file := range reader.File { 150 rc, err := file.Open() 151 if err != nil { 152 return err 153 } 154 filename := dest + file.Name 155 if file.FileInfo().IsDir() { 156 _ = createDir(filename, file.FileInfo().Mode()) 157 continue 158 } 159 w, err := createFile(filename) 160 if err != nil { 161 _ = rc.Close() 162 return err 163 } 164 _, err = io.Copy(w, rc) 165 _ = w.Close() 166 _ = rc.Close() 167 if err != nil { 168 return err 169 } 170 } 171 return nil 172 } 173 174 func createDir(dir string, perm os.FileMode) error { 175 if perm == 0 { 176 perm = 0755 177 } 178 return os.MkdirAll(dir, perm) 179 } 180 181 func createFile(name string) (*os.File, error) { 182 dir := string([]rune(name)[0:strings.LastIndex(name, "/")]) 183 if !DirExist(dir) { 184 err := createDir(dir, 0) 185 if err != nil { 186 return nil, err 187 } 188 } 189 190 return os.Create(name) 191 }