标签:自己的 catch color await txt 二进制 从服务器 状态 output
Stream主要用于序列化地数据处理(read or write input into output sequentially),比如文件读写,网络数据传输, 或任何端到端的数据交换。Stream在处理数据的时候,与传统方式有所不同,传统方式是把数据作为一个整体进行处理,而stream则是把数据分割成一块一块的进行处理,它不是整个数据一起处理,而是一块数据一块数据地处理。以文件读写为例,文件读写的时候,stream并不是一次性地把一个文件中的所有内容都读取到内存中再进行处理(就是再写入到另外一个文件中),而是一块数据一块数据的进行读取,读取完一块数据就处理一块数据(把这块数据写入到另外一个文件中),而不会让它一直在内存中。相比于传统方式,使用stream来处理数据,可以高效的使用内存,更有可能来处理大文件。再以网络数据传输(网上看视频)为例。我们并不是把整个电影都从服务器上下载下来才开始播放,而是一块一块地下载,下载一块,播放一块。服务器一块一块地写数据,浏览器一块一块的读数据。用流处理数据,时间上也比较高效。
在Node.js中,有以下4种流
输入流,就是流中有数据,我们从里面读取数据。输入流负责读取数据,我们只需要从输入流中读取数据。
输出流:它负责向目的地写入数据,而我们只需要向输出流中写入数据。
双向流: 即可以从它里面读取数据,也可以向它里面写入数据
const fs = require(‘fs‘); const readable = fs.createReadStream(‘./data.txt‘); readable.on(‘data‘, data => { console.log(data); })
node read.js 执行程序,控制台输出了buffer, 就是一些二进制数据,默认情况下,从输入流中读取到的内容都是buffer,我们需要手动转化成字符串,调用toString()方法就可以了。console.log(data.toString()) 。假设想用pause模式来读取数据,那就要手动调用输入流的read() 方法了,但还要注意,只有在输入流中有数据的时候,才能调用read() 方法,所以要在readable 事件处理函数中调用read()事件, read()方法,如果读取不到数据,就会返回null
const fs = require(‘fs‘); const readableStream = fs.createReadStream(‘./data.txt‘); readableStream.on(‘readable‘, () => { let chunk; while (null !== (chunk = readableStream.read())) { console.log(chunk.toString()); } })
除了使用事件的方式来从输入流中读取数据,还可以使用异步迭代器来消费输入流(从输入流中读取数据)
const fs = require(‘fs‘); const readableStream = fs.createReadStream(‘./data.txt‘); async function logChunks(readable) { for await (const chunk of readable) { console.log(chunk.toString()); } } logChunks(readableStream);
当然它的底层还是监听readable 事件。除了在异步迭代器,直接处理数据,也可以把流中的数据暂时存储起来,以便日后消费
const fs = require(‘fs‘); const readableStream = fs.createReadStream(‘./data.txt‘); readableStream.setEncoding(‘utf-8‘); async function readableToString(readable) { let result = ‘‘; for await (const chunk of readable) { result += chunk; } return result; } readableToString(readableStream).then(console.log);
如果要处理异常,可以用try/catch 把for await 的处理包起来。说完了输入流,再说输出流。fs.createWriteStream 创建一个输出流,输出流,就是把数据输出到什么地方,因此,它也接受一个参数,就是输出的目的地。我们要做的就是向输出流中写放数据,要调用write() 方法
const fs = require(‘fs‘); const readableStream = fs.createReadStream(‘./data.txt‘); const writeStream = fs.createWriteStream(‘./result.txt‘); readableStream.on(‘data‘, data => { writeStream.write(data); })
const fs = require(‘fs‘); const util = require(‘util‘); const stream = require(‘stream‘); const {once} = require(‘events‘); const readableStream = fs.createReadStream(‘./data.txt‘); const writeStream = fs.createWriteStream(‘./result.txt‘); const finished = util.promisify(stream.finished); async function writeIterableToFile(readable, writable) { for await (const chunk of readable) { if (!writable.write(chunk)) { await once(writable, ‘drain‘); } } writable.end(); // Wait until done. Throws if there are errors. await finished(writable); } writeIterableToFile(readableStream, writeStream)
end() 方法,就表示,向输出流中写完数据了,不会再写了。finished 事件,则中输出流,把所有的数据都写入到的目的地中。当我们手动去读取和写入文件时候,处理有点麻烦,这就用到pipe()方法。上面的可以写成
const fs = require(‘fs‘); const readableStream = fs.createReadStream(‘./data.txt‘); const writeStream = fs.createWriteStream(‘./result.txt‘); readableStream.pipe(writeStream);
pipe() 操作,前一个的输出变成后面一个的输入。readableStream输入流的输出,就是读取到的数据,我们就是要把这些数据写入到输出流中,所以它正好是输出流的输入,因此,就可以用pipe把这两个链接起来。pipe()的操作就相当于
readableStream.on("data", chunk => { // 自动处理了drain事件。 writeStream.write(chunk); }); readableStream.on("end", () => { writeStream.end(); });
标签:自己的 catch color await txt 二进制 从服务器 状态 output
原文地址:https://www.cnblogs.com/SamWeb/p/14316896.html