How do I read a local file in Deno?
⚠ Obsolete: This answer has been broken by the removal of the
'deno'
module in favour of theDeno
global in release v0.3.4.
Deno includes a readFileSync(filename: string): Uint8Array
function in its standard library, which is available at the special import path 'deno'
.
import {readFileSync} from 'deno';
const bytes = readFileSync('./input.txt');
This reads the contents of the file as a byte array. If the file contains text that you want as a string, as in your example, you can use the standard ECMAScript TextDecoder
class (MDN docs).
const utf8Decoder = new TextDecoder('utf-8');
const string = utf8Decoder.decode(bytes);
For the original example, this gives us:
word_count.ts
import {readFileSync} from 'deno';
const countWords = (s: string): number =>
s.split(/\s+/g).filter(w => /[a-z0-9]/.test(w)).length;
const main = async () => {
const decoder = new TextDecoder("utf-8");
const bytes = readFileSync("./input.txt");
const text = decoder.decode(bytes);
const count = countWords(text);
console.log(`I read ${count} words.`);
};
main();
Which produces the desired output:
$ deno ./word_count.ts
I read 9 words.
(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
std 0.62.0
/ Deno 1.2.1
+
Since std v0.62.0
, readFileStr
and readFileStrSync
are removed from Standard Library.
Deno.readTextFile
and Deno.readTextFileSync
have the same API and now are the way to go.
(same for writeFileStr
/ writeFileStrSync
)