V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hoythan
V2EX  ›  Node.js

node js 解压大文件有什么好的解决方案吗?

  •  
  •   hoythan · 2017-08-22 16:15:52 +08:00 · 3908 次点击
    这是一个创建于 2657 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在做 electron 项目,需要兼容 windows 和 macos 系统,使用了很多例如 admzip 等开源项目,但是它们都是加载到内存中处理,导致会提示 Array buffer allocation failed

    不知道大文件应该如何处理 2-5gb ? 请问有啥好的解决方案吗

    26 条回复    2017-08-23 18:43:08 +08:00
    hoythan
        1
    hoythan  
    OP
       2017-08-22 16:17:22 +08:00
    另外不知道 Buffer 清空方法有哪些?
    whileFalse
        2
    whileFalse  
       2017-08-22 16:24:53 +08:00   ❤️ 1
    把 7z 的 dll 和 so 分别包成 7z-win.node 和 7z-mac.node,按需加载
    或者更糙的,直接把 7z 的 exe 拷进去,命令行调用。
    hoythan
        3
    hoythan  
    OP
       2017-08-22 16:32:20 +08:00
    @whileFalse 我也考虑自己写一个 dll 进去,但是 mac 无法使用,你说的 7z 的 dll 调用好像可行,但是 so 是啥文件?
    whileFalse
        4
    whileFalse  
       2017-08-22 16:33:00 +08:00   ❤️ 1
    @hoythan #3 so 是 mac 版的 dll
    hoythan
        5
    hoythan  
    OP
       2017-08-22 16:38:36 +08:00
    @whileFalse 这玩意在哪里呀,我在官方的 git 上木有这个文件貌似
    sunsulei
        6
    sunsulei  
       2017-08-22 16:50:17 +08:00   ❤️ 1
    进到这个帖子差点闪瞎眼,然后切回去后,真瞎了...
    zenxds
        7
    zenxds  
       2017-08-22 17:04:25 +08:00   ❤️ 1
    noder
        8
    noder  
       2017-08-22 17:09:14 +08:00   ❤️ 1
    ttps://www.npmjs.com/package/tar 用 stream
    hoythan
        9
    hoythan  
    OP
       2017-08-22 17:46:27 +08:00
    @zenxds
    @noder
    文档完全懵逼,求教方法。例如 显示所有文件列表
    ```
    tar.list({
    file:filePath
    },[],(e) => {
    console.log(e)
    })
    ```
    yangxiongguo
        10
    yangxiongguo  
       2017-08-22 17:50:14 +08:00   ❤️ 1
    上 libuv
    hoythan
        11
    hoythan  
    OP
       2017-08-22 18:02:05 +08:00
    @zenxds
    @noder
    貌似不支持 zip 文件,只能解压 tar
    hoythan
        12
    hoythan  
    OP
       2017-08-22 18:03:55 +08:00
    @hoythan 是支持 zip 的
    hoythan
        13
    hoythan  
    OP
       2017-08-22 18:05:18 +08:00
    @zenxds
    @noder

    fs.createReadStream(filePath)
    .pipe(tar.x({
    cwd:'C:\\Users\\hoyt\\Desktop\\test\\'
    }))
    .on('entry', entry => {console.log(entry.path)})

    还是 提示
    Array buffer allocation failed
    whileFalse
        14
    whileFalse  
       2017-08-22 20:52:14 +08:00   ❤️ 1
    能上 64 位 nodejs 吗?上了估计能分配足够大的 buffer 了。
    hoythan
        15
    hoythan  
    OP
       2017-08-23 09:55:05 +08:00
    @whileFalse 1g 就差不多崩了,不够稳定。流形式加载貌似也不行
    jianguiqubaa
        16
    jianguiqubaa  
       2017-08-23 13:14:08 +08:00   ❤️ 1
    流式加载是让你一边读一边写,x 是解压,on('entry') 的写法还是把所有的东西都读到内存里了,肯定要崩。
    只是读文件列表的话用 t

    一边读一边解压的话参考文档中这个写法:

    fs.createReadStream('my-tarball.tgz').pipe(
    tar.x({
    strip: 1,
    C: 'some-dir' // alias for cwd:'some-dir', also ok
    })
    )

    https://github.com/npm/node-tar

    另外 1.4G 的内存限制是 v8 给的, 通过参数能加大
    hoythan
        17
    hoythan  
    OP
       2017-08-23 13:22:01 +08:00
    @jianguiqubaa 看这个答案我都想嫁给你了顺便问下有没有办法实现 progress,因为大文件解压需要时间,没有一个 进度 让人觉得时间过的很慢。
    笔芯❤️
    jianguiqubaa
        18
    jianguiqubaa  
       2017-08-23 13:56:55 +08:00   ❤️ 1
    @hoythan

    那就先用 fs.createReadStream 记录 buffer 的大小, 然后 pipe 给 tar,再 pipe 给 fs.createWriteStream
    jianguiqubaa
        19
    jianguiqubaa  
       2017-08-23 13:57:26 +08:00   ❤️ 1
    @hoythan 你是男的,还是算了吧
    jianguiqubaa
        20
    jianguiqubaa  
       2017-08-23 14:52:07 +08:00   ❤️ 1
    哦, 都不用再 pipe 给 fs.createWriteStream 了,tar 把输出搞定了

    fs.createReadStream('my-tarball.tgz')
    .pipe(countFileSize) // 通过 countFileSize 记录已经读取过的文件的大小, 用来计算 progress
    .pipe(
    tar.x({
    strip: 1,
    C: 'some-dir' // alias for cwd:'some-dir', also ok
    })
    )
    hoythan
        21
    hoythan  
    OP
       2017-08-23 15:28:48 +08:00
    @jianguiqubaa 还是会报错 Array buffer allocation failed 唉,昨天一天没试出来
    hoythan
        22
    hoythan  
    OP
       2017-08-23 15:30:02 +08:00
    @jianguiqubaa 在 fs.createReadStream(filePath) 的时候就报错了
    jianguiqubaa
        23
    jianguiqubaa  
       2017-08-23 17:11:17 +08:00   ❤️ 1
    @hoythan

    贴代码出来看看
    hoythan
        24
    hoythan  
    OP
       2017-08-23 17:27:12 +08:00
    @jianguiqubaa 在 electron 中非常正经的使用解压功能,在 windows 系统下
    ```
    fs.createReadStream(filePath).pipe(
    tar.x({
    strip: 1,
    C: 'C:\\Users\\hoyt\\Desktop\\'
    })
    )
    ```
    hoythan
        25
    hoythan  
    OP
       2017-08-23 17:27:41 +08:00
    @hoythan 我可能需要 path.normalize 一下 C? 但是小文件没毛病
    jianguiqubaa
        26
    jianguiqubaa  
       2017-08-23 18:43:08 +08:00   ❤️ 1
    @hoythan

    看了 node-tar 的源码,写入文件的时候各种 writeSync。。。我也是醉了

    换这个吧: https://github.com/mafintosh/tar-fs
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2718 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:34 · PVG 15:34 · LAX 23:34 · JFK 02:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.