生成的ZIP文件为0字节未复制文件,Go函数问题排查求助
问题:生成的ZIP文件大小为0字节,文件未成功复制
现象:生成的ZIP文件大小为0字节,文件未被成功复制;尽管传入的file对象不为空,但仍出现该异常。
相关Go语言函数代码:
func addFileToZip(zipWriter *zip.Writer, file *os.File) error { defer file.Close() fmt.Println("File name:", file.Name()) fi, err := file.Stat() if err != nil { // Could not obtain stat, handle error } fmt.Println("The file is %d bytes long", fi.Size()) w1, err := zipWriter.Create(file.Name()) if err != nil { panic(err) } copyFile, err := io.Copy(w1, file) // (dst, src fmt.Println("Copied file size:", copyFile) if err != nil { fmt.Println("Error copying file to zip:", err) } return err }
问题原因与修复方案
1. 文件读取指针位置错误
传入的file对象可能已被读取过(比如之前执行过Read等操作),导致文件指针停在文件末尾。io.Copy从当前指针位置开始读取,自然读不到任何内容,最终ZIP内的文件大小为0。
修复:调用io.Copy前,将文件指针重置到文件开头:
_, err = file.Seek(0, io.SeekStart) if err != nil { return err }
2. 错误处理不完整
file.Stat()的错误被直接忽略,若该操作失败,后续访问fi.Size()会触发panic,且未将错误返回给调用方。
修复:补充完整的错误处理逻辑:
fi, err := file.Stat() if err != nil { return err }
3. 格式化输出函数误用
fmt.Println不支持占位符格式化,fmt.Println("The file is %d bytes long", fi.Size())会直接输出原始字符串和数字,无法正确展示文件大小。需替换为fmt.Printf:
fmt.Printf("The file is %d bytes long\n", fi.Size())
修复后的完整代码
import ( "archive/zip" "fmt" "io" "os" ) func addFileToZip(zipWriter *zip.Writer, file *os.File) error { defer file.Close() fmt.Println("File name:", file.Name()) fi, err := file.Stat() if err != nil { return err } fmt.Printf("The file is %d bytes long\n", fi.Size()) w1, err := zipWriter.Create(file.Name()) if err != nil { return err // 替换panic,返回错误更优雅 } // 重置文件指针到开头 _, err = file.Seek(0, io.SeekStart) if err != nil { return err } copyFile, err := io.Copy(w1, file) fmt.Println("Copied file size:", copyFile) if err != nil { fmt.Println("Error copying file to zip:", err) return err } return nil }
内容的提问来源于stack exchange,提问作者balu vanan
相关产品推荐
相关产品推荐

