Node.js流编程:高效处理数据的秘诀
立即解锁
发布时间: 2025-08-19 01:17:24 阅读量: 1 订阅数: 4 


Node.js设计模式与最佳实践
### Node.js 流编程:高效处理数据的秘诀
#### 1. 空间效率
在处理数据时,流为我们提供了一种高效的方式,尤其是在处理大数据文件时。传统的缓冲数据并一次性处理的方式存在诸多问题。例如,当我们需要读取一个数百兆甚至数GB的大文件时,使用那种在文件完全读取后返回大缓冲区的API就不是一个好主意。想象一下同时读取几个这样的大文件,我们的应用程序很容易就会耗尽内存。此外,V8中的缓冲区大小不能超过0x3FFFFFFF字节(略小于1GB),所以在耗尽物理内存之前,我们可能就会遇到问题。
##### 1.1 使用缓冲API进行Gzip压缩
下面是一个使用缓冲API的简单命令行界面(CLI)应用程序,用于将文件压缩为Gzip格式:
```javascript
const fs = require('fs');
const zlib = require('zlib');
const file = process.argv[2];
fs.readFile(file, (err, buffer) => {
zlib.gzip(buffer, (err, buffer) => {
fs.writeFile(file + '.gz', buffer, err => {
console.log('File successfully compressed');
});
});
});
```
将上述代码保存为`gzip.js`,然后使用以下命令运行:
```bash
node gzip <path to file>
```
如果选择一个足够大的文件(例如略大于1GB),我们会收到一个错误消息,提示文件大小超过了允许的最大缓冲区大小:
```
RangeError: File size is greater than possible Buffer: 0x3FFFFFFF bytes
```
这表明我们采用了错误的方法。
##### 1.2 使用流进行Gzip压缩
为了让我们的Gzip应用程序能够处理大文件,我们可以使用流式API。以下是修改后的代码:
```javascript
const fs = require('fs');
const zlib = require('zlib');
const file = process.argv[2];
fs.createReadStream(file)
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream(file + '.gz'))
.on('finish', () => console.log('File successfully compressed'));
```
流的接口和可组合性使得代码简洁、优雅。这个程序可以平稳地处理任何大小的文件,并且理想情况下内存利用率是恒定的。
#### 2. 时间效率
考虑一个将文件压缩并上传到远程HTTP服务器的应用程序,服务器再将其解压缩并保存到文件系统。如果客户端使用缓冲API实现,上传将在整个文件读取和压缩完成后才开始;而服务器端的解压缩也只有在接收到所有数据后才会开始。
使用流可以更好地实现这个功能。在客户端,流允许我们在从文件系统读取数据块后立即进行压缩和发送;在服务器端,流允许我们在接收到每个数据块后立即进行解压缩。
##### 2.1 服务器端代码
创建一个名为`gzipReceive.js`的模块,包含以下代码:
```javascript
const http = require('http');
const fs = require('fs');
const zlib = require('zlib');
const server = http.createServer((req, res) => {
const filename = req.headers.filename;
console.log('File request received: ' + filename);
req
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream(filename))
.on('finish', () => {
res.writeHead(201, {'Content-Type': 'text/plain'});
res.end('That\'s it\n');
console.log(`File saved: ${filename}`);
});
});
server.listen(3000, () => console.log('Listening'));
```
##### 2.2 客户端代码
创建一个名为`gzipSend.js`的模块,代码如下:
```javascript
const fs = require('fs');
const zlib = require('zlib');
const http = require('http');
const path = require('path');
const file = process.argv[2];
const server = process.argv[3];
const options = {
hostname: server,
port: 3000,
path: '/',
method: 'PUT',
headers: {
filename: path.basename(file),
'Content-Type': 'application/octet-stream',
'Content-Encoding': 'gzip'
}
};
const req = http.request(options, res => {
console.log('Server response: ' + res.statusCode);
});
fs.createReadStream(file)
.pipe(zlib.createGzip())
.pipe(req)
.on('finish', () => {
console.log('File successfully sent');
});
```
##### 2.3 运行步骤
1. 启动服务器:
```bash
node gzipReceive
```
2. 启动客户端,指定
0
0
复制全文
相关推荐










