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

2017-08-22 16:15:52 +08:00
 hoythan

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

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

3700 次点击
所在节点    Node.js
26 条回复
hoythan
2017-08-22 16:17:22 +08:00
另外不知道 Buffer 清空方法有哪些?
whileFalse
2017-08-22 16:24:53 +08:00
把 7z 的 dll 和 so 分别包成 7z-win.node 和 7z-mac.node,按需加载
或者更糙的,直接把 7z 的 exe 拷进去,命令行调用。
hoythan
2017-08-22 16:32:20 +08:00
@whileFalse 我也考虑自己写一个 dll 进去,但是 mac 无法使用,你说的 7z 的 dll 调用好像可行,但是 so 是啥文件?
whileFalse
2017-08-22 16:33:00 +08:00
@hoythan #3 so 是 mac 版的 dll
hoythan
2017-08-22 16:38:36 +08:00
@whileFalse 这玩意在哪里呀,我在官方的 git 上木有这个文件貌似
sunsulei
2017-08-22 16:50:17 +08:00
进到这个帖子差点闪瞎眼,然后切回去后,真瞎了...
zenxds
2017-08-22 17:04:25 +08:00
noder
2017-08-22 17:09:14 +08:00
ttps://www.npmjs.com/package/tar 用 stream
hoythan
2017-08-22 17:46:27 +08:00
@zenxds
@noder
文档完全懵逼,求教方法。例如 显示所有文件列表
```
tar.list({
file:filePath
},[],(e) => {
console.log(e)
})
```
yangxiongguo
2017-08-22 17:50:14 +08:00
上 libuv
hoythan
2017-08-22 18:02:05 +08:00
@zenxds
@noder
貌似不支持 zip 文件,只能解压 tar
hoythan
2017-08-22 18:03:55 +08:00
@hoythan 是支持 zip 的
hoythan
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
2017-08-22 20:52:14 +08:00
能上 64 位 nodejs 吗?上了估计能分配足够大的 buffer 了。
hoythan
2017-08-23 09:55:05 +08:00
@whileFalse 1g 就差不多崩了,不够稳定。流形式加载貌似也不行
jianguiqubaa
2017-08-23 13:14:08 +08:00
流式加载是让你一边读一边写,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
2017-08-23 13:22:01 +08:00
@jianguiqubaa 看这个答案我都想嫁给你了顺便问下有没有办法实现 progress,因为大文件解压需要时间,没有一个 进度 让人觉得时间过的很慢。
笔芯❤️
jianguiqubaa
2017-08-23 13:56:55 +08:00
@hoythan

那就先用 fs.createReadStream 记录 buffer 的大小, 然后 pipe 给 tar,再 pipe 给 fs.createWriteStream
jianguiqubaa
2017-08-23 13:57:26 +08:00
@hoythan 你是男的,还是算了吧
jianguiqubaa
2017-08-23 14:52:07 +08:00
哦, 都不用再 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
})
)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/384885

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX