我正在编写一个用TypeScript编写的单词计数程序,试图在Deno中运行。我在调用时没有参数,只是deno ./word_count.ts
,因此它应该具有默认的只读文件系统访问权限。我希望我可以将the standard browser fetch()
API和the file:
URL scheme一起使用来从文件系统读取,就像这样:
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();
input.txt
The quick brown fox jumps over the lazy dog.
但是当我尝试时,我发现fetch
不支持file
URL:
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)
如何在Deno中读取本地文件的内容?
答案 0 :(得分:6)
⚠已过时::删除了
'deno'
模块,转而使用了release v0.3.4中的Deno
全局。
Deno在其标准库中包含一个readFileSync(filename: string): Uint8Array
函数,可在特殊的导入路径'deno'
中使用该函数。
import {readFileSync} from 'deno';
const bytes = readFileSync('./input.txt');
这将文件的内容读取为字节数组。如示例中所示,如果文件包含要作为字符串的文本,则可以使用标准ECMAScript TextDecoder
类(MDN docs)。
const utf8Decoder = new TextDecoder('utf-8');
const string = utf8Decoder.decode(bytes);
对于原始示例,这给了我们:
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();
将产生所需的输出:
$ deno ./word_count.ts
I read 9 words.
答案 1 :(得分:2)
readFileStr
中的deno_std
使用readFileStr
中的std/fs
的示例:
import { readFileStr } from 'https://deno.land/std/fs/mod.ts';
const countWords = (s: string): number =>
s.split(/\s+/g).filter(w => /[a-z0-9]/.test(w)).length;
const main = async () => {
const text = await readFileStr('input.txt');
const count = countWords(text);
console.log(`I read ${count} words.`);
};
main();
只需将第一行更改为以下内容,即可使用readFileStr
中的std/fs
来减少下载量:
import { readFileStr } from 'https://deno.land/std/fs/read_file_str.ts';
查看文档,网址为:https://github.com/denoland/deno_std
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 main = async () => {
const text = decoder.decode(await Deno.readFile('input.txt'));
const count = countWords(text);
console.log(`I read ${count} words.`);
};
main();
请注意,您需要将数据明确解码为UTF-8。
查看文档,网址为:https://deno.land/typedoc/index.html#readfile
接受的答案使用readFileSync()
这是一个阻止函数,因此不需要main()
为async
。一个简化的(有效的)示例是:
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.`);
请注意,在任何地方都没有async
,main()
和await
,代码虽然更简单,但是Deno.readFileSync()
会阻塞线程,直到读取文件为止-对于一个简单的脚本,该脚本执行此示例中的步骤序列,就可以了,但是如果它在服务器中的请求处理程序中,则对性能将是一个灾难。
Deno.open
和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 main = async () => {
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.`);
};
main();
您可以将main()
的前两行放在一行中:
const text = decoder.decode(await Deno.readAll(await Deno.open('input.txt')));
但它的可读性较差。
查看文档,网址为:https://deno.land/typedoc/index.html#readall
Deno.open
和Deno.read
您甚至可以使用较低级别的Deno.read
,但随后还必须分配缓冲区
查看文档,网址为:https://deno.land/typedoc/index.html#read
new File()
抽象还有用于读写文件的类样式抽象。
答案 2 :(得分:2)
0.62.0
/ Deno 1.2.1
+ 由于std v0.62.0
,readFileStr
和readFileStrSync
来自标准库,removed。
Deno.readTextFile
和Deno.readTextFileSync
具有相同的API,现在是可行的方法。
(与writeFileStr
/ writeFileStrSync
相同)