node.js流媒体_Node.js流

东门航
2023-12-01

node.js流媒体

什么是流 (What are streams)

Streams are one of the fundamental concepts that power Node.js applications.

流是为Node.js应用程序提供动力的基本概念之一。

They are a way to handle reading/writing files, network communications, or any kind of end-to-end information exchange in an efficient way.

它们是一种以有效方式处理读/写文件,网络通信或任何类型的端到端信息交换的方式。

Streams are not a concept unique to Node.js. They were introduced in the Unix operating system decades ago, and programs can interact with each other passing streams through the pipe operator (|).

流不是Node.js特有的概念。 它们是几十年前在Unix操作系统中引入的,程序可以通过管道运算符( | )使流相互交互。

For example, in the traditional way, when you tell the program to read a file, the file is read into memory, from start to finish, and then you process it.

例如,以传统方式,当您告诉程序读取文件时,会将文件从头到尾读入内存,然后进行处理。

Using streams you read it piece by piece, processing its content without keeping it all in memory.

使用流,您可以逐段读取它,处理其内容而不将其全部保存在内存中。

The Node.js stream module provides the foundation upon which all streaming APIs are build.

Node.js stream模块提供了构建所有流API的基础。

为什么流 (Why streams)

Streams basically provide two major advantages using other data handling methods:

使用其他数据处理方法,流基本上提供了两个主要优点:

  • Memory efficiency: you don’t need to load large amounts of data in memory before you are able to process it

    内存效率 :您无需先在内存中加载大量数据,然后再进行处理

  • Time efficiency: it takes way less time to start processing data as soon as you have it, rather than waiting till the whole data payload is available to start

    时间效率 :拥有数据后立即开始处理数据所需的时间更少,而不必等到整个数据有效负载都可开始使用

流的一个例子 (An example of a stream)

A typical example is the one of reading files from a disk.

一个典型的例子是从磁盘读取文件的例子。

Using the Node fs module you can read a file, and serve it over HTTP when a new connection is established to your http server:

使用Node fs模块,您可以读取文件,并在与http服务器建立新连接时通过HTTP提供文件:

const http = require('http')
const fs = require('fs')

const server = http.createServer(function (req, res) {
  fs.readFile(__dirname + '/data.txt', (err, data) => {
    res.end(data)
  })
})
server.listen(3000)

readFile() reads the full contents of the file, and invokes the callback function when it’s done.

readFile()读取文件的全部内容,并在完成后调用回调函数。

res.end(data) in the callback will return the file contents to the HTTP client.

回调中的res.end(data)会将文件内容返回给HTTP客户端。

If the file is big, the operation will take quite a bit of time. Here is the same thing written using streams:

如果文件很大,则该操作将花费大量时间。 这是使用流编写的相同内容:

const http = require('http')
const fs = require('fs')

const server = http.createServer((req, res) => {
  const stream = fs.createReadStream(__dirname + '/data.txt')
  stream.pipe(res)
})
server.listen(3000)

Instead of waiting until the file is fully read, we start streaming it to the HTTP client as soon as we have a chunk of data ready to be sent.

我们没有等待直到文件被完全读取,而是在准备好要发送的大量数据后立即开始将其流式传输到HTTP客户端。

管() (pipe())

The above example uses the line stream.pipe(res): the pipe() method is called on the file stream.

上面的示例使用stream.pipe(res) :在文件流上调用pipe()方法。

What does this code do? It takes the source, and pipes it into a destination.

该代码的作用是什么? 它获取源,并将其通过管道传输到目标。

You call it on the source stream, so in this case, the file stream is piped to the HTTP response.

您在源流上调用它,因此在这种情况下,文件流通过管道传递到HTTP响应。

The return value of the pipe() method is the destination stream, which is a very convenient thing that lets us chain multiple pipe() calls, like this:

pipe()方法的返回值是目标流,这是非常方便的事情,它使我们可以链接多个pipe()调用,如下所示:

src.pipe(dest1).pipe(dest2)

This construct is the same as doing

此构造与执行相同

src.pipe(dest1)
dest1.pipe(dest2)

流驱动的节点API (Streams-powered Node APIs)

Due to their advantages, many Node.js core modules provide native stream handling capabilities, most notably:

由于它们的优点,许多Node.js核心模块提供了本机流处理功能,最值得注意的是:

  • process.stdin returns a stream connected to stdin

    process.stdin返回连接到stdin的流

  • process.stdout returns a stream connected to stdout

    process.stdout返回连接到stdout的流

  • process.stderr returns a stream connected to stderr

    process.stderr返回连接到stderr的流

  • fs.createReadStream() creates a readable stream to a file

    fs.createReadStream()创建文件的可读流

  • fs.createWriteStream() creates a writable stream to a file

    fs.createWriteStream()创建到文件的可写流

  • net.connect() initiates a stream-based connection

    net.connect()启动基于流的连接

  • http.request() returns an instance of the http.ClientRequest class, which is a writable stream

    http.request()返回http.ClientRequest类的实例,该实例是可写的流

  • zlib.createGzip() compress data using gzip (a compression algorithm) into a stream

    zlib.createGzip()使用gzip(一种压缩算法)将数据压缩到流中

  • zlib.createGunzip() decompress a gzip stream.

    zlib.createGunzip()解压缩gzip流。

  • zlib.createDeflate() compress data using deflate (a compression algorithm) into a stream

    zlib.createDeflate()使用deflate(压缩算法)将数据压缩到流中

  • zlib.createInflate() decompress a deflate stream

    zlib.createInflate()解压缩deflate流

不同类型的流 (Different types of streams)

There are four classes of streams:

流分为四类:

  • Readable: a stream you can pipe from, but not pipe into (you can receive data, but not send data to it). When you push data into a readable stream, it is buffered, until a consumer starts to read the data.

    Readable :可以通过管道传输但不能通过管道传输的流(您可以接收数据,但不能向其发送数据)。 当您将数据推送到可读流中时,将对其进行缓冲,直到使用者开始读取数据为止。

  • Writable: a stream you can pipe into, but not pipe from (you can send data, but not receive from it)

    Writable :您可以通过管道传输而不是从管道传输的流(您可以发送数据,但不能接收数据)

  • Duplex: a stream you can both pipe into and pipe from, basically a combination of a Readable and Writable stream

    Duplex :您可以同时通过管道传输和传输的流,基本上是可读流和可写流的组合

  • Transform: a Transform stream is similar to a Duplex, but the output is a transform of its input

    Transform :转换流类似于双工,但输出是其输入的转换

如何创建可读流 (How to create a readable stream)

We get the Readable stream from the stream module, and we initialize it

我们从stream模块获取Readable流,并对其进行初始化。

const Stream = require('stream')
const readableStream = new Stream.Readable()

Now that the stream is initialized, we can send data to it:

现在,流已初始化,我们可以向其发送数据了:

readableStream.push('hi!')
readableStream.push('ho!')

如何创建可写流 (How to create a writable stream)

To create a writable stream we extend the base Writable object, and we implement its _write() method.

要创建可写流,我们扩展基本Writable对象,并实现其_write()方法。

First create a stream object:

首先创建一个流对象:

const Stream = require('stream')
const writableStream = new Stream.Writable()

then implement _write:

然后实现_write

writableStream._write = (chunk, encoding, next) => {
    console.log(chunk.toString())
    next()
}

You can now pipe a readable stream in:

现在,您可以通过以下方式传递可读流:

process.stdin.pipe(writableStream)

如何从可读流中获取数据 (How to get data from a readable stream)

How do we read data from a readable stream? Using a writable stream:

我们如何从可读流中读取数据? 使用可写流:

const Stream = require('stream')

const readableStream = new Stream.Readable()
const writableStream = new Stream.Writable()

writableStream._write = (chunk, encoding, next) => {
    console.log(chunk.toString())
    next()
}

readableStream.pipe(writableStream)

readableStream.push('hi!')
readableStream.push('ho!')

You can also consume a readable stream directly, using the readable event:

您还可以使用readable事件直接使用可读流:

readableStream.on('readable', () => {
  console.log(readableStream.read())
})

如何将数据发送到可写流 (How to send data to a writable stream)

Using the stream write() method:

使用流write()方法:

writableStream.write('hey!\n')

用信号通知您已结束编写的可写流 (Signaling a writable stream that you ended writing)

Use the end() method:

使用end()方法:

const Stream = require('stream')

const readableStream = new Stream.Readable()
const writableStream = new Stream.Writable()

writableStream._write = (chunk, encoding, next) => {
    console.log(chunk.toString())
    next()
}

readableStream.pipe(writableStream)

readableStream.push('hi!')
readableStream.push('ho!')

writableStream.end()

翻译自: https://flaviocopes.com/nodejs-streams/

node.js流媒体

 类似资料: