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  }