作者:手机用户2502875921 | 来源:互联网 | 2023-08-13 15:35
新一周的工作内容,基本就是研究这个zip文件的解压与压缩了。如上一篇一样,官方文档解释的并不是很清楚。google百度出来的结果都是有问题的,要不就是文件压缩之后,压缩内容变0kb 要不就是文件写入之后解压出来不知道是个什么鬼了。我只用了这一种方式,其他的gzip和tar等有时间在研究。不过我想也都大同小异了。先上代码,然后再说说我在研究的时候遇到的问题吧。
文件压缩
/**
@files:需要压缩的文件
@compreFile:压缩之后的文件
*/
func Compress_zip(files []*os.File, compreFile *os.File) (err error) {zw := zip.NewWriter(compreFile)defer zw.Close()for _, file := range files {err := compress_zip(file, zw)if err != nil {return err}file.Close()}return nil
}/**
功能:压缩文件
@file:压缩文件
@prefix:压缩文件内部的路径
@tw:写入压缩文件的流
*/
func compress_zip(file *os.File, zw *zip.Writer) error {info, err := file.Stat()if err != nil {logs.Error("压缩文件失败:", err.Error())return err}head, err := zip.FileInfoHeader(info)if err != nil {logs.Error("压缩文件失败:", err.Error())return err}head.Method = zip.Deflatefw, err := zw.CreateHeader(head)if err != nil {logs.Error("压缩文件失败:", err.Error())return err}_, err = io.Copy(fw, file)file.Close()if err != nil {logs.Error("压缩文件失败:", err.Error())return err}return nil
}
压缩文件的时候有一个Header的概念
type FileHeader struct {// Name是文件名,它必须是相对路径,不能以设备或斜杠开始,只接受'/'作为路径分隔符Name stringCreatorVersion uint16ReaderVersion uint16Flags uint16Method uint16ModifiedTime uint16 // MS-DOS时间ModifiedDate uint16 // MS-DOS日期CRC32 uint32CompressedSize uint32 // 已弃用;请使用CompressedSize64UncompressedSize uint32 // 已弃用;请使用UncompressedSize64CompressedSize64 uint64UncompressedSize64 uint64Extra []byteExternalAttrs uint32 // 其含义依赖于CreatorVersionComment string
}
以上就是官方文档给出的FileHeader的一些讲解,大概就是描述压缩文件中文件的一些信息的,比方说文件压缩前大小、压缩后大小这些、文件名这些,压缩文件就是创建出zip文件然后用zip.NewWriter()获得对文件的压缩写入流。之后通过压缩写入流,创建出压缩文件的Header 然后把文件写入到Header中。这样就能达到压缩文件的目的了。这之中有一个需要注意的是压缩方式的问题。
const (Store uint16 = 0 Deflate uint16 = 8 )
预定义压缩算法。
这是archive/zip包中预定义的两种压缩方式。一个是仅把文件写入到zip中。不做压缩。一种是压缩文件然后写入到zip中。
head.Method = zip.Deflate
如上就是设置文件的压缩模式。默认的Store模式。就是只保存不压缩的模式。
解压文件
/**
@tarFile:压缩文件路径
@dest:解压文件夹
*/
func DeCompressByPath(tarFile, dest string) error {srcFile, err := os.Open(tarFile)if err != nil {return err}defer srcFile.Close()return DeCompress(srcFile, dest)
}/**
@zipFile:压缩文件
@dest:解压之后文件保存路径
*/
func DeCompress(srcFile *os.File, dest string) error {zipFile, err := zip.OpenReader(srcFile.Name())if err != nil {logs.Error("Unzip File Error:", err.Error())return err}defer zipFile.Close()for _, innerFile := range zipFile.File {info := innerFile.FileInfo()if info.IsDir() {err = os.MkdirAll(innerFile.Name, os.ModePerm)if err != nil {logs.Error("Unzip File Error : " + err.Error())return err}continue}srcFile, err := innerFile.Open()if err != nil {logs.Error("Unzip File Error : " + err.Error())continue}defer srcFile.Close()newFile, err := os.Create(innerFile.Name)if err != nil {logs.Error("Unzip File Error : " + err.Error())continue}io.Copy(newFile, srcFile)newFile.Close()}return nil
}
这个没什么太大问题。只是解压文件出来创建文件夹保存