• Skip to primary navigation
  • Skip to content
  • Skip to primary sidebar

陈文管的博客

分享有价值的内容

  • Android
  • Affiliate
  • SEO
  • 前后端
  • 网站建设
  • 自动化
  • 开发资源
  • 关于

Node.js后端zip压缩文件保存和读取

2020年7月18日 | 最近更新于 下午9:20

如果服务器使用RethinkDB分布式数据库保存JSON数据,在保存的数据量持续增加的时候,网页端做数据查询操作时浏览器非常容易卡死,而且查询耗时,这个时候就需要另外考虑JSON数据的保存和读取,RethinkDB并不能满足需求。经过对比测试,JSON文本内容保存成txt文档之后,再压缩成zip文件占用空间非常小,可以作为优化方案来实施。

比如以JSON格式化方式保存成txt文档,文件大小是7.6MB,不做格式化保存文件大小是4MB,以压缩文件方式保存大小是175KB,不考虑格式化保存,压缩比是23.4倍。也就是保存1GB的JSON数据,只需要43.76MB的存储空间。来看下用JS方式保存和读取zip文件的具体代码逻辑实现。

一、Archiver方式保存zip实现

var fs = require('fs');
var archiver = require('archiver');

var filePath = "../xxxxxxx.zip";
var fileName = "xxxxxxx.txt";
var output = fs.createWriteStream(filePath);
var archive = archiver('zip', {
 zlib: {level: 9},
 forceLocalTime: true,
});
archive.on('error', function (err) {
 console.log(err);
});
archive.pipe(output);
archive.append(jsonContent, {name: fileName});
archive.finalize();

filePath就是保存的zip压缩文件路径,fileName就是保存在zip压缩文件内的文件名,jsonContent就是要保存的JSON文本内容。

向压缩文件追加的内容也可以是一个Buffer、文件流或者目录:

// 追加一个文件流
archive.append(fs.createReadStream(__dirname + "/sourceFiles/1.txt"), { name: "file1.txt" });
// 追加一个string
archive.append("string content!", { name: "file2.txt" });
// 追加一个buffer
var buffer = Buffer.from("buff content!");
archive.append(buffer, { name: "file3.txt" });
// 追加一个现有文件
archive.file("sourceFiles/1.txt", { name: "file4.txt" });
// 追加一个目录(子目录也会被增加)
archive.directory("sourceFiles/", "new-subdir");
// 追加一个目录——类似于直接复制
archive.directory("sourceFiles/");
// 将目标目录中的文件追加至根目录
archive.directory("sourceFiles/", false);
// 新增空文件夹
archive.append('', { name: "empty-dir/" });

二、unzip方式获取压缩文件内容

如果只是解压文件到指定目录比较简单:

fs.createReadStream('path/to/archive.zip').pipe(unzip.Extract({ path: 'output/path' }));

但这边的需求不是解压文件,而是直接获取zip压缩文件里面的内容,这边用stream的Writable对象来获取写文件流里面的内容,在’finish’回调之后,拿到文件流完整内容。

如果不使用文件流数据,要调用entry.autodrain()释放内存,否则会耗尽服务器的内存。

var fs = require('fs');
var unzip = require("unzip");
var stream = require('stream');

var input = fs.createReadStream(".../archive.zip");
input.pipe(unzip.Parse()).on('entry', function (entry) {
    var fileName = entry.path;
    var type = entry.type; // 'Directory' or 'File'
    var data = [];
    if (fileName is target File you need) {
        var writeStream = new stream.Writable();
        writeStream.writable = true;
        writeStream._write = (chunk, encoding, next) => {
            data.push(chunk);
            next()
        }
        writeStream.on('finish', () => {
            var content = Buffer.concat(data);
        });
        entry.pipe(writeStream);
    } else {
        entry.autodrain();
    }
});

三、参考资料

npmjs unzip

npmjs unzipper

node-unzip, node.js 跨平台使用流进行解压缩

Archiver zip打包

Node.js Stream(流)–文件操作

JSZip How to read a file

Understanding Streams in Node.js

NodeJS API Stream

 

 

扩展阅读:

AngularJS集成HighCharts动态绘制CPU和内存变化曲线

 

 

转载请注明出处:陈文管的博客 – Node.js后端zip压缩文件保存和读取

 

扫码或搜索:文呓

博客公众号

微信公众号 扫一扫关注

博客公众号
博客公众号

GitHub

https://github.com/wenguan0927

近期文章

  • Android平台动画类型详解
  • Kotlin null 详解
  • Android 残影数字动画实现详解
  • Android 卡片旋转切换动效实现详解
  • Android 心率动画自定义控件实现

友情链接

崔庆才的个人博客

Trinea  (codeKK)

Piasy

Paincker

wanandroid

陈祖杰的BLOG

闽ICP备18001825号-1 · Copyright © 2023 · Powered by chenwenguan.com