24-流操作-stream

157 阅读2分钟

流操作-stream

// nodejs的核心模块,基本上都是stream的实例,比如 process.stdout http.clientRequest,对于大部分的nodejs开发着来说,平常不会直接用到 stream模块.只需要了解stream的机制就可以了
// 而对于想要实现的自定义stream实例的开发着来说,就需要好好研究stream的扩展API了,比如gulp的内部实现就用到了大量的自定义stream类型
// 简单的例子,几行代码就实现了读取文件内容,打印到控制台

stream 分类

// 在nodejs中,有四张stream类型
// 1. Readable 用来读取数据 比如 fs.createReadStream()
// 2. Writable 用来写内容, 比如 fs.createWriteStream()
// 3. Duplex 可读+可写 比如 net.Socket()
// 4. Transform 在读写过程中,可以对数据进行修改,比如 zlib.createDeflate (数据压缩或者解压)

Readable Stream

// 以下是nodejs中常见的Readable Stream, 当然还有其他的可以自行查找
// http.IncomingRequest  fs.createReadStream  process.stdin

// 例子1
fs.readFile("./index.txt", "utf-8", (err, content) => {
  console.log("例子1: 读取的内容是[%s],", content); // 例子1: 读取的内容是[你是我是字节007]
});
// 例子2
const readStream = fs.createReadStream("./index.txt");
let content = "";
readStream.setEncoding("utf-8");
readStream.on("data", (chunk) => {
  content += chunk;
});
readStream.on("end", (chunk) => {
  console.log("例子2: 读取的内容是[%s]", content); // 例子2: 读取的内容是[你是我是字节007]
});
// 例子3
// 这里使用 .pipe(dest) 好处在于,如果原文件比较大,可以降低内容占用
fs.createReadStream("./index.txt").pipe(process.stdout); // 你是我是字节007
// 注意:这里只是原封不动的将内容输出到控制台,所以实际上跟前面的两个例子有细微的差异,可以稍微的修改,达到相同的效果
const end = function () {
  process.stdout.write("]");
};
const fileStream = fs.createReadStream("./index.txt");
fileStream.on("end", end);
fileStream.pipe(process.stdout);
process.stdout.write("例子3:读取的内容是["); // 例子3:读取的内容是[你是我是字节007]

Writeable Stream

// 同样以写文件为例子,比如想要将 hello world 写到 indexe.txt

// 例子1
const content = "hello world";
const fildepath = "./index.txt";
fs.writeFile(fildepath, content, (err) => {
  console.log(err);
});
// 例子2
const content1 = "hello world 1";
const writeStream = fs.createWriteStream(fildepath);
writeStream.write(content1);
writeStream.end();

Duplex Stream

// 最长见的Duplex Stream就是 net.Socket 实例了,在前面的文章里有接触过,这里直接上代码,这里包含服务端客户端代码

// 服务端代码
const net = require("net");
const opt = {
  host: "127.0.0.1",
  port: "3000",
};
const server = net.createServer((Socket) => {
  Socket.on("data", (data) => {
    console.log("客户端发送信息: ", data.toString()); // 客户端发送信息:  我是 发送给客户端的信息
  });
  Socket.write("hello world");
});
server.listen(opt.port, opt.host, () => {
  console.log(server.address()); // { address: '127.0.0.1', family: 'IPv4', port: 3000 }
});

const client = net.connect(opt, () => {
  client.write("我是 发送给客户端的信息");
});
client.on("data", (data) => {
  console.log("客户端获取到服务端的响应: %s", data); // 客户端获取到服务端的响应: hello world
  client.end();
});

Transform Stream

// TransformStream是DuplexStream的特例,也就是说,TransformStream同时可读可写,跟DuplexStream的区别在于,TransformStream的输出和输入是存在相关性的
// 常见的TransformStream包括 zlib crypto ,简单举例

const zlib = require("zlib");
const gzip = zlib.createGzip();
const inFile = fs.createReadStream("./aa.txt");
const out = fs.createWriteStream("./aa.txt.gz");
inFile.pipe(gzip).pipe(out);

相关链接

https://nodejs.org/api/stream.html