如何在Deno中读取本地文件?

7 typescript deno

我正在编写一个用TypeScript编写的字数统计程序,我正试图在Deno中运行.我只是在没有参数deno ./word_count.ts的情况下调用它,所以它应该具有默认的只读文件系统访问权限.我希望,我可能能够使用标准的浏览器fetch()API使用file:URL方案从文件系统读取,如下所示:

  word_count.ts
const countWords = (s: string): number =>
s.split(/\s+/g).filter(w => /[a-z0-9]/.test(w)).length;

const main = async () => {
    const text = await (await fetch("file:///./input.txt")).text();
    const count = countWords(text);
    console.log(`I read ${count} words.`);
};

main();
Run Code Online (Sandbox Code Playgroud)   input.txt
The quick brown fox jumps over the lazy dog.
Run Code Online (Sandbox Code Playgroud)

但是当我尝试时,我看到我发现它fetch不支持fileURL:

Error: an error occurred trying to connect: invalid URL, scheme must be http
    at FetchResponse.onMsg (deno/js/fetch.ts:121:21)
    at FetchRequest.onMsg (deno/js/fetch.ts:152:19)
    at onFetchRes (deno/js/fetch.ts:28:8)
    at onMessage$1 (deno/js/main.ts:30:7)
Run Code Online (Sandbox Code Playgroud)

如何在Deno中读取本地文件的内容?

rsp*_*rsp 31

更新:async function main() { ... }不再需要包装代码,因为 Deno 现在支持顶级await

使用内置 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.`);
Run Code Online (Sandbox Code Playgroud)

请参阅以下文档:https : //doc.deno.land/builtin/stable#Deno.readTextFile

使用内置 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.`);
Run Code Online (Sandbox Code Playgroud)

请注意,您需要将数据显式解码为 UTF-8。

请参阅以下文档:https : //deno.land/typedoc/index.html#readfile

使用阻塞读取

接受的答案用途readFileSync()这是一个阻塞函数,因此main()存在async不需要(更新:它不再需要无阻塞await以及)。一个简化(和工作)的例子是:

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.`);
Run Code Online (Sandbox Code Playgroud)

请注意,没有await任何地方,因此代码稍微简单一些(更新:在 Deno 支持顶级之前await,简单性的差异更大)但Deno.readFileSync()会阻塞线程,直到读取文件 - 对于执行一系列操作的简单脚本像这个例子中的步骤这很好,但是如果它在服务器中的请求处理程序中,那么这对性能来说将是一场灾难。

使用低级Deno.openDeno.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.`);
Run Code Online (Sandbox Code Playgroud)

您可以将前两行main()放在一行中:

const text = decoder.decode(await Deno.readAll(await Deno.open('input.txt')));
Run Code Online (Sandbox Code Playgroud)

但它的可读性会降低。

请参阅以下文档:https : //deno.land/typedoc/index.html#readall

甚至低级Deno.openDeno.read

您甚至可以使用更低的杠杆,Deno.read但是您还必须分配缓冲区

请参阅以下文档:https : //deno.land/typedoc/index.html#read

使用new File()抽象

还有一个用于读取和写入文件的类样式抽象。

请参阅以下文档:https : //deno.land/typedoc/classes/deno.file.html

  • 这个答案现在已经过时了 https://github.com/denoland/deno/releases/tag/v1.2.1 `BREAKING(std/fs):remove readFileStr and writeFileStr` 。现在 Deno 有 `Deno.readTextFileSync` 和 `Deno.readTextFile` 可供替代。 (5认同)

小智 6

Deno 'deno'在其标准库中包含一个函数,该函数可在特殊的导入路径中使用Deno.

import {readFileSync} from 'deno';

const bytes = readFileSync('./input.txt'); 
Run Code Online (Sandbox Code Playgroud)

这将文件的内容作为字节数组读取.如果文件包含您希望作为字符串的文本(如示例中所示),则可以使用标准ECMAScript readFileSync(filename: string): Uint8Array类(MDN文档).

const utf8Decoder = new TextDecoder('utf-8');
const string = utf8Decoder.decode(bytes);
Run Code Online (Sandbox Code Playgroud)

对于原始示例,这给了我们:

  'deno'
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();
Run Code Online (Sandbox Code Playgroud)

这产生了所需的输出:

$ deno ./word_count.ts
I read 9 words.