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 the Deno 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)