dongqingcheng2903 2013-12-03 17:00
浏览 471
已采纳

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

is there a easy way to unzip file with golang ?

right now my code is:

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
}
  • 写回答

4条回答 默认 最新

  • dongshi8359 2014-07-16 23:48
    关注

    Slight rework of the OP's solution to create the containing directory dest if it doesn't exist, and to wrap the file extraction/writing in a closure to eliminate stacking of defer .Close() calls per @Nick Craig-Wood's comment:

    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)
    
            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
    }
    

    Note: Updated to include Close() error handling as well (if we're looking for best practices, may as well follow ALL of them).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波
  • ¥15 针对曲面部件的制孔路径规划,大家有什么思路吗
  • ¥15 钢筋实图交点识别,机器视觉代码
  • ¥15 如何在Linux系统中,但是在window系统上idea里面可以正常运行?(相关搜索:jar包)
  • ¥50 400g qsfp 光模块iphy方案
  • ¥15 两块ADC0804用proteus仿真时,出现异常
  • ¥15 关于风控系统,如何去选择
  • ¥15 这款软件是什么?需要能满足我的需求
  • ¥15 SpringSecurityOauth2登陆前后request不一致