gpt4 book ai didi

go - 使用缓冲区作为输出时,压缩文件夹已损坏

转载 作者:IT王子 更新时间:2023-10-29 02:30:49 25 4
gpt4 key购买 nike

我正在尝试将 zip 文件写入缓冲区而不是文件,以最终将其传递给 http 响应。下面是模拟它的代码。

package main

import (
"archive/zip"
"bytes"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
)

func main() {
data, err := zipit("myfolder")
if err != nil {
panic(err)
}
ioutil.WriteFile("output.zip", data, os.ModePerm)
}

func zipit(source string) ([]byte, error) {
buf := new(bytes.Buffer)
archive := zip.NewWriter(buf)
defer archive.Close()
info, err := os.Stat(source)
if err != nil {
return nil, nil
}

var baseDir string
if info.IsDir() {
baseDir = filepath.Base(source)
}
filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}

if baseDir != "" {
header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))
}

if info.IsDir() {
header.Name += "/"
} else {
header.Method = zip.Deflate
}

writer, err := archive.CreateHeader(header)
if err != nil {
return err
}

if info.IsDir() {
return nil
}

file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
return err
})
return buf.Bytes(), err
}

但是,此 zip 过程的输出已损坏。如果我使用文件而不是缓冲区,它会起作用。

zipfile, err := os.Create(target)
if err != nil {
return err
}
defer zipfile.Close()

archive := zip.NewWriter(zipfile)
defer archive.Close()

os.File 和 bytes.Buffer 都实现了 io.Writer 接口(interface),并且有资格作为写入器传递给 zip.NewWrite() 方法。

任何解决此问题的方向将不胜感激。

最佳答案

您在关闭 zip.Writer 之前读取了缓冲区,因此需要刷新到缓冲区的任何最终数据都已丢失。您应该删除 defer archive.Close() 并在从缓冲区中获取字节之前关闭存档。例如

    err = archive.Close()
return buf.Bytes(), err

它适用于您的文件盒,因为您推迟关闭文件。延迟将以后进先出的方式应用,因此存档会在文件关闭之前关闭。

关于go - 使用缓冲区作为输出时,压缩文件夹已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55623678/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com