管道流
Deno 实现了 Web 标准的流(streams),这带来了许多优点。流最实用的功能之一是它们如何在不同源之间进行管道传输(piped)。
流的一个常见用例是在不将整个文件缓冲到内存中的情况下下载文件。首先,我们打开一个要写入的文件
const download = await Deno.open("example.html", { create: true, write: true });
现在我们向一个网页发出请求
const req = await fetch("https://examples.deno.land");
我们可以将此响应直接导入到文件中。在一个更真实的例子中,我们会处理不良请求,但在这里我们只使用空值合并运算符。与其打开文件并手动将 fetch 主体管道传输到其中,我们也可以直接使用 `Deno.writeFile`。
req.body?.pipeTo(download.writable);
管道可以连接很多东西。例如,我们可以将刚刚下载的文件管道传输到标准输出(stdout)。我们还可以将流通过转换器(transformers)进行管道传输,以获得更有趣的结果。在这种情况下,我们将文件通过一个流进行管道传输,该流将在终端中高亮显示所有 "<" 字符。
首先,我们将从标准库中导入一个工具来帮助我们。
import { bgBrightYellow } from "jsr:@std/fmt/colors";
然后我们将创建一个转换流(transform stream)工具类
class HighlightTransformStream extends TransformStream<string, string> {
constructor() {
super({
transform: (chunk, controller) => {
controller.enqueue(chunk.replaceAll("<", bgBrightYellow("<")));
},
});
}
}
让我们打开文件进行读取
const example = await Deno.open("example.html", { read: true });
现在我们可以将文件的结果,管道传输到 TextDecoderStream,再传输到我们的自定义转换类,然后通过 TextEncoderStream 传回,最后传输到标准输出(stdout)
await example.readable
.pipeThrough(new TextDecoderStream())
.pipeThrough(new HighlightTransformStream())
.pipeThrough(new TextEncoderStream())
.pipeTo(Deno.stdout.writable);
使用 Deno CLI 在本地运行此示例
deno run -N -R -W https://docs.deno.org.cn/examples/scripts/piping_streams.ts