为了账号安全,请及时绑定邮箱和手机立即绑定

使用 golang 解压缩文件的简单方法

使用 golang 解压缩文件的简单方法

Go
收到一只叮咚 2021-07-07 15:02:25
有没有一种简单的方法可以用 golang 解压缩文件?现在我的代码是:func Unzip(src, dest string) error {    r, err := zip.OpenReader(src)    if err != nil {        return err    }    defer r.Close()    for _, f := range r.File {        rc, err := f.Open()        if err != nil {            return err        }        defer rc.Close()        path := filepath.Join(dest, f.Name)        if f.FileInfo().IsDir() {            os.MkdirAll(path, f.Mode())        } else {            f, err := os.OpenFile(                path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())            if err != nil {                return err            }            defer f.Close()            _, err = io.Copy(f, rc)            if err != nil {                return err            }        }    }    return nil}
查看完整描述

3 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

OP 解决方案的轻微返工以创建包含目录(dest如果它不存在),并将文件提取/写入包装在一个闭包中以消除defer .Close()每个@Nick Craig-Wood评论的调用堆栈:


func Unzip(src, dest string) error {

    r, err := zip.OpenReader(src)

    if err != nil {

        return err

    }

    defer func() {

        if err := r.Close(); err != nil {

            panic(err)

        }

    }()


    os.MkdirAll(dest, 0755)


    // Closure to address file descriptors issue with all the deferred .Close() methods

    extractAndWriteFile := func(f *zip.File) error {

        rc, err := f.Open()

        if err != nil {

            return err

        }

        defer func() {

            if err := rc.Close(); err != nil {

                panic(err)

            }

        }()


        path := filepath.Join(dest, f.Name)


        // Check for ZipSlip (Directory traversal)

        if !strings.HasPrefix(path, filepath.Clean(dest) + string(os.PathSeparator)) {

            return fmt.Errorf("illegal file path: %s", path)

        }


        if f.FileInfo().IsDir() {

            os.MkdirAll(path, f.Mode())

        } else {

            os.MkdirAll(filepath.Dir(path), f.Mode())

            f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())

            if err != nil {

                return err

            }

            defer func() {

                if err := f.Close(); err != nil {

                    panic(err)

                }

            }()


            _, err = io.Copy(f, rc)

            if err != nil {

                return err

            }

        }

        return nil

    }


    for _, f := range r.File {

        err := extractAndWriteFile(f)

        if err != nil {

            return err

        }

    }


    return nil

}

注意:更新为包括 Close() 错误处理(如果我们正在寻找最佳实践,不妨遵循所有这些)。


查看完整回答
反对 回复 2021-07-12
  • 3 回答
  • 0 关注
  • 346 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信