(Update: wrapping code in async function main() { ... }
is no longer needed because Deno now supports top-level await
)
Using built-in Deno.readTextFile
const countWords = (s: string): number =>
s.split(/\s+/g).filter(w => /[a-z0-9]/.test(w)).length;
const text = await Deno.readTextFile('input.txt');
const count = countWords(text);
console.log(`I read ${count} words.`);
See the docs at: https://doc.deno.land/builtin/stable#Deno.readTextFile
Using built-in Deno.readFile
const countWords = (s: string): number =>
s.split(/\s+/g).filter(w => /[a-z0-9]/.test(w)).length;
const decoder = new TextDecoder('utf-8');
const text = decoder.decode(await Deno.readFile('input.txt'));
const count = countWords(text);
console.log(`I read ${count} words.`);
Note that you need to explicitly decode the data as UTF-8.
See the docs at: https://deno.land/typedoc/index.html#readfile
Using blocking reads
The accepted answer uses readFileSync()
which is a blocking function so the main()
being async
is not needed (Update: it is no longer needed for non-blocking await
as well). A simplified (and working) example would be:
const countWords = (s: string): number =>
s.split(/\s+/g).filter(w => /[a-z0-9]/.test(w)).length;
const decoder = new TextDecoder('utf-8');
const text = decoder.decode(Deno.readFileSync('input.txt'));
const count = countWords(text);
console.log(`I read ${count} words.`);
Note that there is no await
anywhere, so the code is slightly simpler (Update: before Deno supported top-level await
the difference in simplicity was bigger) but the Deno.readFileSync()
will block the thread until the file is read - for a simple script that does a sequence of steps like in this example this is fine, but if it was inside a request handler in a server then it would be a disaster for the performance.
Using lower-level Deno.open
and Deno.readAll
const countWords = (s: string): number =>
s.split(/\s+/g).filter(w => /[a-z0-9]/.test(w)).length;
const decoder = new TextDecoder('utf-8');
const file = await Deno.open('input.txt');
const text = decoder.decode(await Deno.readAll(file));
const count = countWords(text);
console.log(`I read ${count} words.`);
You could put the first two lines of main()
in a single line:
const text = decoder.decode(await Deno.readAll(await Deno.open('input.txt')));
but it would be less readable.
See the docs at: https://deno.land/typedoc/index.html#readall
Even lower-level Deno.open
and Deno.read
You could use even lower-lever Deno.read
but then you'd also have to allocate the buffers
See the docs at: https://deno.land/typedoc/index.html#read
Using new File()
abstraction
There is also a class-style abstraction for reading and writing files.
See the docs at: https://deno.land/typedoc/classes/deno.file.html
fetch()
syntax for files, track it @ github.com/denoland/deno/issues/2150 – Spruill