Reading Data
enumerate
works with any iterable, including a ReadableStream
(which is
an AsyncIterable
). proc
favors using ReadableStream
because it works
automatically with AsyncIterable
back-propagation, so it will close
automatically if the iteration terminates early.
Reading from stdin
You can get a ReadableStream<Uint8Array>
from stdin
like this:
Deno.stdin.readable
. We use enumerate(...)
to add an Enumerable
wrapper.
File example.ts
:
import { enumerate } from "jsr:@j50n/proc@0.22.2";
for await (const line of enumerate(Deno.stdin.readable).lines) {
console.log(line);
}
Notice the use of .lines
. This converts the data to lines of text from
Uint8Array
, or byte buffers.
To print War and Peace, line by line, to console:
cat warandpeace.txt.gz | gunzip | deno run example.ts
This operation will consume stdin
and close it.
See Enumerable
Reading from File
Just as for stdin
, files have a ReadableStream<Uint8Array>
view. We can read
the file directly.
In this case, the file is compressed, so we need to decompress it before we can
extract the lines of text. I am using the gunzip
transform function to do
this. This is using Deno's new DecompressionStream("gzip")
transformer stream
behind the scenes. gunzip
is a convenience function provided by proc
.
import { enumerate, gunzip } from "jsr:@j50n/proc@0.22.2";
const file = Deno.open("warandpeace.txt.gz");
for await (const line of enumerate(file.readable).transform(gunzip).lines) {
console.log(line);
}
No need to explicitly close the file. ReadableStream
with iteration is
magical.
I could have also used this:
enumerate(file.readable).run("gunzip").lines;
to pipe the data through the command gunzip
in a child process.
Neither the transformer version nor the child-process version blocks the main JavaScript/Typescript thread. Both versions are non-blocking.