JavaScript中读取文件的各种方法

开发 前端
如果你在寻找一个快速且简单的方法,fs.promises​是一个不错的选择,它提供了一个Promise接口,让你能够以现代的异步语法来处理文件读取。

在JavaScript中,尤其是配合Node.js这样的运行时环境,有多种方式可以读取服务器上的文件。每种方法都有其适用场景和优缺点。今天,我们就来比较几种常见的文件读取方法,看看哪一种最适合你的需求。

太长不看版

如果你在寻找一个快速且简单的方法,fs.promises是一个不错的选择,它提供了一个Promise接口,让你能够以现代的异步语法来处理文件读取。然而,如果你更倾向于同步方法,你可能会更喜欢fs.readFileSync,虽然它会阻塞当前线程直到文件读取完成。最后,如果你在寻找一种能够提供更好的性能的方法,你可能会想要考虑使用fs.readFile,这是Node.js中最传统的异步文件读取方法,使用回调函数来处理结果。

使用fs.promises

const fs = require('fs/promises');
const readFile = fs.readFile;
readFile("lipsum.txt", { encoding: 'utf-8' })
.then((data) => {...})
.catch((err) => {...});

这种方法使用了Node.js提供的fs.promises接口,它返回一个Promise对象,可以链式调用.then()和.catch()方法来处理异步操作的结果。

使用fs.readFile和util.promisify

const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
readFile("lipsum.txt", { encoding: 'utf-8' })
.then((data) => {...})
.catch((err) => {...});

这种方法通过util.promisify将传统的回调函数转换成返回Promise的函数,使得你可以用更现代的异步语法来处理文件读取。

使用fs.readFileSync

const fs = require('fs');
const readFileSync = fs.readFileSync;
var data = readFileSync("lipsum.txt", { encoding: 'utf-8' });

这是同步方法,它会阻塞当前线程直到文件读取完成,适用于对性能要求不高且文件不大的情况。

使用await和fs.readFileSync

const fs = require('fs');
const readFileSync = fs.readFileSync;
async function f(name, options) {
  return readFileSync(name, options);
}

这种方法结合了async/await语法和同步读取,可以在需要同步行为但希望代码看起来更异步的情况下使用。

使用fs.readFile

const fs = require('fs');
const readFile = fs.readFile;
readFile('lipsum.txt', function read(err, data) {...});

这是Node.js中最传统的异步文件读取方法,使用回调函数来处理结果。

性能比较

我进行了一项小的基准测试,重复读取磁盘上的同一个文件,并记录读取文件50,000次所需的毫秒数。文件相对较小,略多于一千字节。我使用的是一台拥有数十个Ice Lake Intel核心和大量内存的大型服务器。测试使用了Node.js 20.1和Bun 1.0.14。Bun是一个与Node.js竞争的JavaScript运行时[1]。

多次运行基准测试,我报告了所有情况下的最佳结果。你的结果可能会有所不同。

方法

Node.js 时间

Bun 时间

fs.promises

2400 毫秒

110 毫秒

fs.readFile 和 util.promisify

1500 毫秒

180 毫秒

fs.readFileSync

140 毫秒

140 毫秒

await fs.readFileSync

220 毫秒

180 毫秒

fs.readFile

760 毫秒

90 毫秒

至少在我的系统上,在这次测试中,使用Node.js时fs.promises明显比其他方法成本更高。Bun运行时在这次测试中比Node.js快得多。

结果看起来对fs.promises更不利,因为readFileSync使用了300毫秒的CPU时间,而fs.promises使用了7秒的CPU时间。这是因为fs.promises在基准测试期间触发了多个核心的工作。

将文件大小增加到32kB并不会改变结论。如果你使用更大的文件,许多Node.js的案例会因“堆限制Allocation failed”而失败。Bun即使在大文件下也能继续工作。测试结果在Bun中没有改变结论:在我的测试中,即使对于大文件,fs.readFile也是一致更快的。

本文译自:https://lemire.me/blog/2024/03/12/how-to-read-files-quickly-in-javascript/

Reference

[1]Bun是一个与Node.js竞争的JavaScript运行时: https://bun.dev/

责任编辑:武晓燕 来源: 前端F2E
相关推荐

2011-07-05 09:50:42

JAVA

2024-01-31 09:24:58

2010-08-02 16:58:08

Flex配置文件

2020-10-16 18:35:53

JavaScript字符串正则表达式

2013-03-08 11:03:17

PowerShellVHDResizer虚拟磁盘

2010-06-03 08:55:43

LINQ

2010-08-02 16:47:46

Flex

2021-03-08 09:32:04

Python文件命令

2009-12-25 10:28:10

WPF路由事件

2009-12-25 13:09:49

Linux Vi

2020-08-24 08:05:47

JavaScriptJavaScript 页面

2020-08-01 16:19:13

JavaScript字符串开发

2009-12-21 14:31:39

Fedora core

2023-08-25 16:37:08

Pandas测试

2024-08-19 01:00:00

读取配置文件接口应用程序

2015-03-13 13:50:47

Java读取文件夹大小Java读取文件Java读取

2009-08-25 17:31:57

C#读取文件

2022-05-31 16:00:46

Go 编程语言复制文件Go 标准库

2020-06-23 14:51:13

JavaScript字符字符串

2013-01-07 10:44:00

JavaScriptjQueryJS
点赞
收藏

51CTO技术栈公众号