golang 咋这么恶心,解压 zip 文件居然要一大串代码,这不应该是语言内置一行搞定的吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
bthulu
V2EX    Go 编程语言

golang 咋这么恶心,解压 zip 文件居然要一大串代码,这不应该是语言内置一行搞的吗?

  •  
  •   bthulu 2022-12-03 16:43:28 +08:00 10256 次点击
    这是一个创建于 1048 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这简直不能忍啊

    C#版

    ZipFile.ExtractToDirectory("source", "target"); 

    Golang 版

    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 } 
    50 条回复    2022-12-26 15:07:14 +08:00
    XieGP
        1
    XieGP  
       2022-12-03 16:46:48 +08:00   2
    py 写多了吗:)
    loolac
        2
    loolac  
       2022-12-03 16:50:40 +08:00
    当然,还需要一台电脑 ~
    ChrisFreeMan
        3
    ChrisFreeMan  
       2022-12-03 16:51:22 +08:00   3
    真正的逻辑代码也没几行,大部分都是错误处理和 IO 释放
    GeruzoniAnsasu
        4
    GeruzoniAnsasu  
       2022-12-03 17:03:25 +08:00
    C: ……
    yazinnnn
        5
    yazinnnn  
       2022-12-03 17:04:12 +08:00   1
    ?迷惑发言
    wwqgtxx
        6
    wwqgtxx  
       2022-12-03 17:05:55 +08:00   7
    今日迷惑行为大赏
    icepie
        7
    icepie  
       2022-12-03 17:06:53 +08:00   24
    Golang 版
    Unzip("source", "target")
    yazinnnn
        8
    yazinnnn  
       2022-12-03 17:13:17 +08:00   1
    楼主发的这些帖子看上去跟个流量号似的
    ClarkAbe
        9
    ClarkAbe  
       2022-12-03 17:23:52 +08:00 via Android
    zz 发言......自个封装一个就能实现, 你要是懒得封装只能说你不要用这种接近底层的语言了....去 py 吧
    HugoChao
        10
    HugoChao  
       2022-12-03 17:38:46 +08:00
    你代码都有了为什么不封装一下呢
    oldshensheep
        11
    oldshensheep  
       2022-12-03 17:43:30 +08:00   8
    因为
    if err != nil {
    return err
    }
    xavierskip
        12
    xavierskip  
       2022-12-03 17:59:34 +08:00
    你写一个包给大家用不好了。
    Jooooooooo
        13
    Jooooooooo  
       2022-12-03 18:15:01 +08:00
    golang 的 Unzip 不也是一行?
    QI41mOpKTG3jLhDt
        14
    QI41mOpKTG3jLhDt  
       2022-12-03 18:20:13 +08:00
    把这里面封一层再调用不就行了吗
    liuidetmks
        15
    liuidetmks  
       2022-12-03 18:23:03 +08:00 via iPhone
    c 不是更麻烦?
    deorth
        16
    deorth  
       2022-12-03 18:27:51 +08:00 via Android
    要在脑子里打开
    swulling
        17
    swulling  
       2022-12-03 18:30:19 +08:00 via iPhone   1
    https://github.com/artdarek/go-unzip

    随便找个库就行,go 标准库有些比较底层
    shakukansp
        18
    shakukansp  
       2022-12-03 18:36:10 +08:00
    ???
    yanqiyu
        19
    yanqiyu  
       2022-12-03 18:57:09 +08:00   16
    Go 语言并没有将解压 zip 文件作为语言内置的功能,这是因为 Go 的设计理念是尽可能保持简单,而不是提供尽可能多的功能。因此,如果你需要在 Go 中解压 zip 文件,就需要使用第三方库来实现这个功能。这些库通常都提供了一些简单的函数,可以让你在 Go 代码中很容易地解压 zip 文件。比如,你可以使用 Go 语言内置的 "archive/zip" 包来解压 zip 文件,它提供了一个名为" Unzip "的函数,可以让你很容易地解压 zip 文件。

    不是我说的,是 ChatAI 说的
    https://twitter.com/clowwindy/status/1598979812831657984/photo/1
    infinityv
        20
    infinityv  
       2022-12-03 19:08:31 +08:00 via iPhone   3
    @yanqiyu #19 chatgpt 今天给我说 go 是一门动态语言,我说你特么扯淡呢吧,然后他就向我道歉,说我是对的。
    seakingii
        21
    seakingii  
       2022-12-03 19:17:42 +08:00   1
    c#的这个函数方法也是语言内置的,是.NET 类库里的. 语言和库都搞不清楚....
    dw2693734d
        22
    dw2693734d  
       2022-12-03 19:49:49 +08:00
    Golang 确实没有内置的函数来直接解压 zip 文件,但是它提供了一个标准库 "archive/zip",可以用来方便地解压 zip 文件。

    解压 zip 文件的一般步骤如下:

    导入 "archive/zip" 包
    读取 zip 文件内容,比如使用 ioutil.ReadFile()
    创建一个 zip.Reader ,用来处理 zip 文件内容
    遍历 zip.Reader.File ,获取每一个文件,并解压它
    代码示例如下:

    ```
    import (
    "archive/zip"
    "io"
    "io/ioutil"
    "os"
    "path/filepath"
    )

    // 解压 zip 文件
    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
    }
    ```

    from OpenAI
    MMMMMMMMMMMMMMMM
        23
    MMMMMMMMMMMMMMMM  
       2022-12-03 19:52:11 +08:00   1
    不想造轮子就找 lib 呗,多简单一事

    小编这边推荐你使用易语言哦,不仅也只需要一行,还是中文的哦~
    ghostwind
        24
    ghostwind  
       2022-12-03 19:56:15 +08:00
    go 真正麻烦的解压缩 rar 文件
    LykorisR
        25
    LykorisR  
       2022-12-03 19:58:57 +08:00
    ??
    liaohongxing
        26
    liaohongxing  
       2022-12-03 21:27:20 +08:00
    rar 是专利格式 ,go 官方类库解压 rar 估计不会有 。
    liubaicai
        27
    liubaicai  
       2022-12-03 21:43:03 +08:00
    ZipFile 也不是 c#自带的吧
    leavic
        28
    leavic  
       2022-12-03 21:50:14 +08:00   2
    你们回什么贴啊,block 走人就是了。
    mmdsun
        29
    mmdsun  
       2022-12-03 23:16:09 +08:00   1
    seakingii
        30
    seakingii  
       2022-12-03 23:42:22 +08:00
    @mmdsun 这只是官方实现的库,不是"C#语言自带的功能"...
    微软官方实现的库确实用起来方便,比如 File.WriteAllText , 一次性写入文本到一个文件,也很方便,但和"C#语言自带"这个概念不相符,其实用 VB.NET 一样可以用这些函数,只要.NET 支持的语言都可以.
    seakingii
        31
    seakingii  
       2022-12-03 23:44:45 +08:00
    需求是无穷无尽的,官方也只能挑着实现了,人力毕竟有限
    djoiwhud
        32
    djoiwhud  
       2022-12-04 02:06:12 +08:00 via Android
    go 语言怎么这么恶心。自动把账号功能收到的资金转账到楼主的账号,这么基础的功能都不能自动实现吗?

    本来楼主就要实现万亿资产的目标,都怪 go 太垃圾。
    ewBuyVmLZMZE
        33
    ewBuyVmLZMZE  
       2022-12-04 05:30:34 +08:00
    你贴的代码有一定的安全性问题,可以参考我这个实现。

    https://github.com/bookstairs/bookhunter/blob/master/internal/file/decompress.go
    changyang
        34
    changyang  
       2022-12-04 09:04:38 +08:00
    @yanqiyu 恩必
    LANB0
        35
    LANB0  
       2022-12-04 10:57:11 +08:00
    C:你在说什么? golang 这点代码都还不够我 zip 格式头逐字段解析呢?
    vanton
        36
    vanton  
       2022-12-04 12:29:09 +08:00
    有那么多库可以用,你这样自己找麻烦么
    liubaicai
        37
    liubaicai  
       2022-12-04 12:37:17 +08:00
    @mmdsun “这些示例需要将以下 NuGet 包添加到项目中:” 你仔细看看
    blankmiss
        38
    blankmiss  
       2022-12-04 12:45:55 +08:00
    java 不是一样的 正是因为这样才有很多轮子作者
    JohnBull
        39
    JohnBull  
       2022-12-04 13:20:24 +08:00
    shell 省事,可你嫌不 cool 啊
    oldshensheep
        40
    oldshensheep  
       2022-12-04 13:41:06 +08:00
    @blankmiss Java 可不一样
    https://gist.github.com/oldshensheep/bea5bd4c313f27884bc87dced9917bf6
    带完整的错误处理和流关闭处理,核心函数一共 19 行。
    Fuhuang
        41
    Fuhuang  
       2022-12-04 14:09:16 +08:00
    不,是你原来习惯的.Net 太实用了
    adoyle
        42
    adoyle  
       2022-12-04 14:43:48 +08:00   1
    已 block (善意提醒以后别回我的评论,我看不到的)
    lincanbin
        43
    lincanbin  
       2022-12-04 15:58:22 +08:00
    slice contain 、max 、min 也没有。
    习惯就好。
    bthulu
        44
    bthulu  
    OP
       2022-12-05 08:25:51 +08:00
    @liubaicai 仔细看过了, 并不需要导入任何 nuget 包
    bthulu
        45
    bthulu  
    OP
       2022-12-05 08:29:10 +08:00
    @adoyle block 谁还不会啊, 已 block (善意提醒以后别回我的评论,我也看不到的)
    dragonsunmoon
        46
    dragonsunmoon  
       2022-12-05 16:48:27 +08:00
    只能说明 go 的生态还不行, 自带的标准库比不上 .net 和 java. 开源的工具库项目里, 很少有类似有基金会支持的开源项目, 代码质量和后续维护都令人担忧, 大家都不得不自己造轮子
    dragonsunmoon
        47
    dragonsunmoon  
       2022-12-05 17:33:25 +08:00
    有一说一, go 的标准库是真的简陋, 不好用. 就连个 decimal 标准库里都没有. 感觉设计实现标准库的人, 完全没有做过业务系统, api 的易用性完全是一点都不考虑, 唉...
    blsm
        48
    blsm  
       2022-12-07 14:20:09 +08:00
    go 的生态确实不太行,标准库太简陋了。不内置,官方出个工具包也行
    chinaufo
        49
    chinaufo  
       2022-12-19 18:17:16 +08:00
    golang 内置不行就是不行,为什么不敢承认呢
    allgy
        50
    allgy  
       2022-12-26 15:07:14 +08:00
    厨子不行怪灶台
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2668 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 15:04 PVG 23:04 LAX 08:04 JFK 11:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86