dan*_*neu 12
这是使用 Go 的内置递归文件遍历器的解决方案,因为到目前为止最佳答案已经实现了它们自己的文件遍历器:
另外,我今天在生成 zip 文件时发现的一些发现可能会让其他人头疼:
w.Create(zippath)w.Create("manifest.xml")w.Create("a/b/c.css)filepath.WalkReadDir
package main
import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
)
// Zips "./input" into "./output.zip"
func main() {
file, err := os.Create("output.zip")
if err != nil {
panic(err)
}
defer file.Close()
w := zip.NewWriter(file)
defer w.Close()
walker := func(path string, info os.FileInfo, err error) error {
fmt.Printf("Crawling: %#v\n", path)
if err != nil {
return err
}
if info.IsDir() {
return nil
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
// Ensure that `path` is not absolute; it should not start with "/".
// This snippet happens to work because I don't use
// absolute paths, but ensure your real-world code
// transforms path into a zip-root relative path.
f, err := w.Create(path)
if err != nil {
return err
}
_, err = io.Copy(f, file)
if err != nil {
return err
}
return nil
}
err = filepath.Walk("input", walker)
if err != nil {
panic(err)
}
}
- 无需先读再写。只做 io.Copy(dst, src) 所以目前 io.Copy(f, file) 你也关闭 w 两次,这不是一个错误,但 zip.Close 不会关闭底层资源和目标文件在程序的开头没有被关闭。所以目前可能会出现问题。程序也不完整(没有包规范,没有导入规范等) (3认同)
- (作为记录,我的回答确实包括了@mh-cbon 的所有建议,iirc。谢谢。) (2认同)