zip文件怎么解压 zip文件怎么打开 vivo仿ios-1zip文件下载( 二 )


var fileContents stringif compression == noCompression {fileContents, i, err = readString(bs, i, int(uncompressedSize))if err != nil {return nil, 0, err}} else {end := i + int(compressedSize)if end > len(bs) {return nil, 0, errOverranBuffer}flateReader := flate.NewReader(bytes.NewReader(bs[i:end]))defer flateReader.Close()read, err := ioutil.ReadAll(flateReader)if err != nil {return nil, 0, err}fileContents = string(read)i = end}并返回填充好的结构体实例:
return &localFileHeader{signature: signature,version: version,bitFlag: bitFlag,compression: compression,lastModified: lastModified,crc32: crc32,compressedSize: compressedSize,uncompressedSize: uncompressedSize,fileName: fileName,extraField: extraField,fileContents: fileContents,}, i, nil}04 读取辅助函数现在我们只定义那些带有边界检查的读取辅助函数,使用 Go 的内置库来处理二进制编码 。
var errOverranBuffer = fmt.Errorf(&34;Overran buffer&34;)func readUint32(bs []byte, offset int) (uint32, int, error) {end := offset + 4if end > len(bs) {return 0, 0, errOverranBuffer}return binary.LittleEndian.Uint32(bs[offset:end]), end, nil}func readUint16(bs []byte, offset int) (uint16, int, error) {end := offset+2if end > len(bs) {return 0, 0, errOverranBuffer}return binary.LittleEndian.Uint16(bs[offset:end]), end, nil}并且基本上只对获取的字节和字符串进行边界检查 。
func readBytes(bs []byte, offset int, n int) ([]byte, int, error) {end := offset + nif end > len(bs) {return nil, 0, errOverranBuffer}return bs[offset:offset+n], end, nil}func readString(bs []byte, offset int, n int) (string, int, error) {read, end, err := readBytes(bs, offset, n)return string(read), end, err}05 MSDOS 时间我猜在创建 zip 时,MSDOS 时间格式很流行 。但它在今天并不流行,所以花了一些时间才最终用一些代码(模仿 C 语言)找到对该格式的解释[2] 。
func msdosTimeToGoTime(d uint16, t uint16) time.Time {seconds := int((t & 0x1F) * 2)minutes := int((t >> 5) & 0x3F)hours := int(t >> 11)day := int(d & 0x1F)month := time.Month((d >> 5) & 0x0F)year := int((d >> 9) & 0x7F) + 1980return time.Date(year, month, day, hours, minutes, seconds, 0, time.Local)}06 测试运行:
$ go build$ ./gozip test.zip2021-11-23 23:04:20 +0000 UTC hello.text Hello!这看起来不错!现在让我们尝试压缩多个文件 。
$ cat bye.textAu revoir!$ rm test.zip$ zip test.zip *.textadding: bye.text (stored 0%)adding: hello.text (stored 0%)$ ./gozip test.zip2021-11-24 03:40:00 +0000 UTC bye.text Au revoir!2021-11-23 23:04:20 +0000 UTC hello.text Hello!一切正常 。
07 总结实际上,还有许多标准需要处理(例如目录)和许多常见的扩展,本文没有涉及 。
文件末尾还有一些空间,这可能是 “central directory” 元数据,但我还没有深入研究 。如果你有兴趣可以查阅相关资料了解最后剩下的部分内容 。
原文链接:http://notes.eatonphil.com/implementing-zip-in-go-unzipping.html
参考资料[1]
这里: http://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
[2]
【zip文件怎么解压 zip文件怎么打开 vivo仿ios-1zip文件下载】对该格式的解释: http://groups.google.com/g/comp.os.msdos.programmer/c/ffAVUFN2NbA