猿问

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

有没有一种简单的方法可以用 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

}


收到一只叮咚
浏览 347回答 3
3回答

PIPIONE

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() 错误处理(如果我们正在寻找最佳实践,不妨遵循所有这些)。
随时随地看视频慕课网APP

相关分类

Go
我要回答