大家好,刚好要花23小时10分钟,所以很显然有些问题了,我的内存中有一个zip文件,我想将该文件复制一个,然后将一些文件添加到副本中并通过HTTP返回文件,它可以工作,但是当我打开文件时,它似乎已损坏
outFile, err := os.OpenFile("./template.zip", os.O_RDWR, 0666)
if err != nil {
log.Fatalf("Failed to open zip for writing: %s", err)
}
defer outFile.Close()
zipw := zip.NewWriter(outFile)
fmt.Println(reflect.TypeOf(zipw))
for _, appCode := range appPageCodeText {
f, err := zipw.Create(appCode.Name + ".jsx")
if err != nil {
log.Fatal(err)
}
_, err = f.Write([]byte(appCode.Content)) //casting it to byte array and writing to file
}
// Clean up
err = zipw.Close()
if err != nil {
log.Fatal(err)
}
defer outFile.Close()
//Get the Content-Type of the file
//Create a buffer to store the header of the file in
FileHeader := make([]byte, 512)
//Copy the headers into the FileHeader buffer
outFile.Read(FileHeader)
//Get content type of file
fmt.Println(reflect.TypeOf(outFile))
//Get the file size
FileStat, _ := outFile.Stat() //Get info from file
FileSize := strconv.FormatInt(FileStat.Size(), 10) //Get file size as a string
buffer := make([]byte, FileStat.Size())
outFile.Read(buffer)
//Send the headers
w.Header().Set("Content-Disposition", "attachment; filename="+"template.zip")
w.Header().Set("Content-Type", "application/zip")
w.Header().Set("Content-Length", FileSize)
outFile.Seek(0, 0)
// io.Copy(w, buffer) //'Copy' the file to the client
w.Write(buffer)
最佳答案
Read
的前512个字节outFile
编码为FileHeader
,这意味着它们没有被读入buffer
,这意味着该文件的前512个字节不会发送到客户端。您执行了Seek
,但为时已晚,无法使用-那时buffer
的内容已经设置好了。您需要更早移动“搜索”或写入两个缓冲区,或者只是删除不必要的FileHeader
读取。 FileHeader
。为什么会这样呢?您知道文件的类型是什么,只需编写它即可。因此,不需要单独读取前512个字节。 zip.Writer
写入文件,从磁盘重新打开文件,将其读取为字节数组,然后将该字节数组写入HTTP客户端,而不是在磁盘上创建文件,您可以直接将zip.Writer
直接写入HTTP客户端(如果您不关心设置Content-Length
),也可以将其写入bytes.Buffer
,然后将该缓冲区复制到HTTP客户端(如果准确的Content-Length
对您)。 第一个版本如下所示:
w.Header().Set("Content-Disposition", "attachment; filename=template.zip")
w.Header().Set("Content-Type", "application/zip")
zipw := zip.NewWriter(w)
// Your for loop to add items to the zip goes here.
//
zipw.Close() // plus error handling
第二个版本如下所示:
buffer := &bytes.Buffer{}
zipw := zip.NewWriter(buffer)
// Your for loop to add items to the zip goes here.
//
zipw.Close() // plus error handling
w.Header().Set("Content-Disposition", "attachment; filename=template.zip")
w.Header().Set("Content-Type", "application/zip")
w.Header().Set("Content-Length", strconv.FormatInt(buffer.Length(), 10))
io.Copy(w, buffer) // plus error handling
关于go - 编辑内存中的zip文件并通过http响应返回它会导致文件损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59725717/