node.js stream setEncoding 遇到的坑

本文介绍了一个Node.js中文件读取的基础操作案例,并针对不同文件类型的编码选择进行了探讨,特别是对于非文本文件如PPT等进行hex编码而非默认的utf-8编码的原因进行了分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

return new Promise((resolve,reject) => {
        // 创建可读流
        var readerStream = fs.createReadStream(file_path);

        // 设置编码为 utf8。
        if(encoding == null)readerStream.setEncoding('utf8');
        else readerStream.setEncoding(encoding);

        let data = null;

        readerStream.on('data', function(chunk) {
            data += chunk;
        });

        readerStream.on('end',function(){
            resolve(data);
        });

        readerStream.on('error', function(err){
            reject(err);
        });
    });

上面一段代码作为读写文件的基本操作。但值得注意的是 readerStream.setEncoding 编码选择。

查了一下API文档,说明略少,utf-8 和 hex 两种编码类型:

 

踩坑点

读取一个ppt格式文件时,使用了utf-8编码,结果报出buffer长度超出边界值。这是由于编码过程,ppt文件数据转换成字符串数据类型已超过buffere边界,buffere相当于一个数组。因此注意编码需要使用hex

<think>好的,用户想了解如何使用Node.js原生流实现最常用的代码段。首先,我需要回忆一下Node.js中流的基本概念和类型。Node.js的流分为可读流、可写流、双工流和转换流,用户可能需要具体的例子,比如文件复制、数据转换或者HTTP请求处理。 接下来,用户提到的是“最常用代码段”,所以应该挑选几个典型的场景。比如,读取文件并写入另一个文件,这是最基本的流操作,使用pipe方法。但用户要求原生实现,可能需要展示如何手动处理data和end事件,而不依赖pipe。 然后,考虑错误处理。流在操作中可能会产生错误,比如文件不存在或者写入权限问题,所以每个流都应该有错误监听器,这是必要的部分。 另外,用户可能对数据转换感兴趣,比如使用转换流来处理数据。例如,将输入的文本全部转为大写,再输出。这时候需要用到Transform类,实现_transform方法。 还有,处理HTTP请求和响应也是常见的流应用场景。比如,接收上传的文件并保存到本地,或者将服务器文件流式传输给客户端。这时候需要处理可读流和可写流的组合。 可能还需要提到管道链,比如多个流连接在一起,比如读取文件,压缩,再加密,最后写入。但用户要求最常用,可能先举简单的例子,再稍微提一下链式调用。 需要确保代码示例符合Node.js的语法,正确使用事件监听器,比如data、end、error、finish等事件。同时,要注意流的正确关闭和错误处理,避免资源泄漏。 另外,要注意中文回答,结构清晰,分步骤说明每个代码段的作用和实现原理。比如,先讲文件复制,再讲转换流,再讲HTTP流的使用。 可能还需要提醒用户关于流的背压问题,不过如果是基础代码段,可能暂时不需要深入,但如果有高级应用,可以简单提及。 最后,检查代码的正确性,比如是否正确使用双工流或转换流,是否正确导出模块等。确保每个示例都能独立运行,并且处理了所有必要的错误情况。</think>以下是使用 Node.js 原生流实现的 5 个最常用代码段及详细说明: 1. **基础文件复制流** ```javascript const fs = require('fs'); // 创建可读流 const readStream = fs.createReadStream('input.txt'); // 创建可写流 const writeStream = fs.createWriteStream('output.txt'); // 通过管道连接 readStream.pipe(writeStream); // 错误处理 readStream.on('error', (err) => console.error('读取错误:', err)); writeStream.on('error', (err) => console.error('写入错误:', err)); writeStream.on('finish', () => console.log('文件复制完成')); ``` 2. **手动处理数据流** ```javascript const readStream = fs.createReadStream('data.log'); readStream .on('data', (chunk) => { console.log(`收到 ${chunk.length} 字节数据`); // 这里可以进行数据处理 }) .on('end', () => console.log('数据读取完成')) .on('error', (err) => console.error('流错误:', err)); ``` 3. **HTTP 服务流式响应** ```javascript const http = require('http'); http.createServer((req, res) => { const fileStream = fs.createReadStream('large-video.mp4'); res.setHeader('Content-Type', 'video/mp4'); fileStream .on('open', () => fileStream.pipe(res)) .on('error', (err) => { res.statusCode = 500; res.end('文件读取错误'); }); }).listen(3000); ``` 4. **转换流实现(大写转换器)** ```javascript const { Transform } = require('stream'); class UpperCaseTransform extends Transform { _transform(chunk, encoding, callback) { const upper = chunk.toString().toUpperCase(); this.push(upper); callback(); } } // 使用示例 fs.createReadStream('input.txt') .pipe(new UpperCaseTransform()) .pipe(fs.createWriteStream('output-upper.txt')); ``` 5. **多流管道链(压缩加密管道)** ```javascript const zlib = require('zlib'); const crypto = require('crypto'); fs.createReadStream('data.csv') .pipe(zlib.createGzip()) // 压缩 .pipe(crypto.createCipheriv( // 加密 'aes-256-cbc', key, iv )) .pipe(fs.createWriteStream('data.csv.enc.gz')) .on('finish', () => console.log('处理完成')); ``` **关键要点说明:** 1. 所有流操作都应包含错误处理 2. `pipe()` 方法自动处理背压控制 3. 转换流需要实现 `_transform` 方法 4. 流事件的生命周期管理(open/data/end/error/finish) 5. 组合流操作时注意流的类型匹配(可读流 → 可写流) **高级技巧:** - 使用 `pipeline()` 替代 `pipe()` 链以获得更好的错误处理 ```javascript const { pipeline } = require('stream'); pipeline( fs.createReadStream('input'), zlib.createGzip(), fs.createWriteStream('output.gz'), (err) => err ? console.error('管道错误:', err) : null ); ``` 这些代码段涵盖了文件操作、网络传输、数据处理等常见场景,建议根据具体需求进行参数调整和功能扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值