文件读取
nodejs 中的文件读取,支持异步读取以及同步读取
-
异步读取
fs.readFile(path[, options], callback)-
path: string | Buffer | URL | integer 文件名或文件描述符
-
options: (这是一个可选项) object<encoding | flag | signal> | string
其中 encoding: string | null 是读取文件的编码格式, 默认值为 null
flag: string 是支持的文件系统 flags, 默认值是 'r'
signal: AbortSignal 允许中止正在进行中的 readFile
-
callback: function , 有两个回调参数 err, data
err: 错误消息
data: string | buffer
-
const { readFile } = require("node:fs");
const path = require("node:path");
readFile(path.resolve(__dirname, "./观书有感.txt"), "utf-8", (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
promise 类型的 readFile
// 使用 promises 去读取文件
fs.readFile(path.resolve(__dirname, "./观书有感.txt"), "utf-8").then(
(data, err) => {
if (err) {
console.log(err);
} else {
console.log(data);
}
}
);
返回的是一个 promise 类型的数据
文件可读流 fs.createReadStream(path[, options])
js 中的事件都继承至 eventEmitter, 我们可以通过这个事件中的方法监听数据流
const readStram = createReadStream(path.resolve(__dirname, "./观书有感.txt"));
readStram.on("data", (chunk) => {
// 返回的是 Buffer 数据
console.log(chunk);
console.log(chunk.toString());
});
readStram.on("end", () => {
console.log("读取完成");
});
readStram.on("error", (err) => {
console.log(err);
});
总结:
所有的异步读取文件的 api 都有一个回调函数, 这个回调函数包含了读取的结果和错误异常
同时可选配置项中的 flag 支持多种选择配置, 默认值为 r
-
可选配置项
-
'a':打开文件进行追加。如果文件不存在,则创建该文件。 -
'ax':类似于'a'但如果路径存在则失败。
'ax': Like'a'but fails if the path exists.-
'a+':打开文件进行读取和追加。如果文件不存在,则创建该文件。 -
'ax+':类似于'a+'但如果路径存在则失败。 -
'as':以同步模式打开文件进行追加。如果文件不存在,则创建该文件。 -
'as+':以同步模式打开文件进行读取和追加。如果文件不存在,则创建该文件。 -
'r':打开文件进行读取。如果文件不存在,则会发生异常。 -
'rs':打开文件以同步模式读取。如果文件不存在,则会发生异常。 -
'r+':打开文件进行读写。如果文件不存在,则会发生异常。 -
'rs+':以同步模式打开文件进行读写。指示操作系统绕过本地文件系统缓存。
这主要用于在 NFS 挂载上打开文件,因为它允许跳过可能过时的本地缓存。它对 I/O 性能有非常实际的影响,因此除非需要,否则不建议使用此标志。
这不会将
fs.open()或fsPromises.open()变成同步阻塞调用。如果需要同步操作,应该使用类似fs.openSync()的东西。-
'w':打开文件进行写入。创建(如果它不存在)或截断(如果它存在)该文件。 -
'wx':类似于'w'但如果路径存在则失败。 -
'w+':打开文件进行读写。创建(如果它不存在)或截断(如果它存在)该文件。 -
'wx+':类似于'w+'但如果路径存在则失败。
-
-
同步读取
readFileSync添加上 Sync 代表它为同步读取文件, 但是如果文件读取过大会等待很长时间, 建议使用异步读取的方式获取文件
文件写入
nodejs 中的文件写入,支持异步读取以及同步读取
- 异步写入
fs.writeFile(file, data[, options], callback)
file: string | Buffer | URL | integer 文件名或文件描述符
data: string>| Buffer| TypedArray | DataView
options: Object | string
-
flag参见 支持文件系统flags。默认值:'w'。 -
flush如果所有数据都成功写入文件,并且flush是true,则使用fs.fsync()来刷新数据。默认值:false。
const data = Buffer.from("hello world");
writeFile(
path.resolve(__dirname, "./观书有感.txt"),
//"追加内容",
data,
{ flag: "a" },
(err) => {
if (err) {
console.log(err);
} else {
console.log("写入成功");
}
}
);
promise 类型的 writeFile
const fs = require("node:fs/promises");
const data = Buffer.from("hello world");
fs.writeFile(path.resolve(__dirname, "./观书有感.txt"), data, { flag: "a" })
.then(() => {
console.log("写入成功");
})
.catch((err) => {
console.log(err);
});
- 同步写入
writeFileSync 添加上 Sync 代表它为同步写入文件
writeFileSync(path.resolve(__dirname, "./观书有感.txt"), "写入成功", {
flag: "a",
});
文件写入流 fs.createWriteStream([options])
const writeStream = createWriteStream(
path.resolve(__dirname, "./观书有感.txt"),
{
flags: "a",
}
);
writeStream.write("\n 写入流");
writeStream.end();
writeStream.on("finish", () => {
console.log("写入完成");
});
文件读写流可以通过 pipe 管道进行写入
const resadStream = fs.createReadStream('./观书有感.txt')
const writeStream = fs.createWriteStream('./观书有感2.txt')
// 这句话的意思是 将 resadStream 中的数据写入到 writeStream
resadStream.pipe(writeStream)
总结:
文件如果不存在, 他会帮我们创建并写入
- writeFile // 异步写入 四个参数, 第一个为文件路径 第二个为写的内容, 第三个是可选项配置, 第四个是回调函数
- writeFileSync // 同步写入
- appendFile // 异步追加写入
- appendFileSync // 同步追加写入
- createWriteStream // 创建写入流
文件写入的场景: - 下载文件 - 安装软件 - 保存程序日志, 如 git - 编辑器保存文件 - 视频录制等
当需要持久化保存数据的时候, 应该想到文件写入
文件夹操作
-
fs.mkdir(path[, options], callback)三个参数:第一个为文件夹路径, 第二个为可选项配置, 第三个为回调函数
fs.mkdir(path.resolve(__dirname, "./test"), { recursive: true }, (err) => {
if (err) {
console.log(err);
} else {
console.log("创建成功");
}
});
- mkdirSync // 同步创建文件夹
mkdirSync(path.resolve(__dirname, "./test1"), { recursive: true });
-
fs.readdir(path[, options], callback)读取当前文件所在文件夹下的文件目录数组
三个参数:第一个为文件夹路径,第二个可选项配置, 第三个为回调函数
readdir(path.resolve(__dirname, "./"), (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
// 打印值
[
'node_modules',
'package-lock.json',
'package.json',
'readFile.js',
'test',
'test1',
'观书有感.txt'
]
-
fs.rmdir(path[, options], callback)options 的取值
rmdir(path.resolve(__dirname, "./test"), (err) => {
if (err) {
console.log(err);
} else {
console.log("删除成功");
}
});
-
fs.rm(path[, options], callback)options 的取值
rm(path.resolve(__dirname, "./test"), { recursive: true }, (err) => {
if (err) {
console.log(err);
} else {
console.log("删除成功");
}
});
-
fs.rmSync(path[, options]) -
optionsforce当为true时,如果path不存在,则异常将被忽略。默认值:false。maxRetries如果遇到EBUSY、EMFILE、ENFILE、ENOTEMPTY或EPERM错误,Node.js 将在每次尝试时以retryDelay毫秒的线性退避等待时间重试该操作。此选项表示重试次数。如果recursive选项不为true,则忽略此选项。默认值:0。recursive如果为true,则执行递归目录删除。在递归模式下,操作将在失败时重试。默认值:false。retryDelay重试之间等待的时间(以毫秒为单位)。如果recursive选项不为true,则忽略此选项。默认值:100。
rmSync(path.resolve(__dirname, "./test"), { recursive: true });文件移动和重命名
使用 rename 和 renameSync 来移动和重命名文件夹或文件
fs.rename(oldPath, newPath, callback)fs.renameSync(oldPath, newPath)文件删除
fs.unlink(path, callback)unlink(path.resolve(__dirname, "./观书有感.txt"), (err) => { if (err) { console.log(err); } else { console.log("删除成功"); } });fs.unlinkSync(path)unlinkSync(path.resolve(__dirname, "./观书有感.txt"));fs.rm(path[, options], callback)rm(path.resolve(__dirname, "./test"), { recursive: true }, (err) => { if (err) { console.log(err); } else { console.log("删除成功"); } });fs.rmSync(path[, options])rmSync(path.resolve(__dirname, "./test"), { recursive: true });注意:unlink 不能用来删除文件, rm 可以删除文件和文件夹文件移动和重命名
使用 rename 和 renameSync 来移动和重命名文件夹或文件
fs.rename(oldPath, newPath, callback)// 进行重命名 rename( path.resolve(__dirname, "./观书有感.txt"), path.resolve(__dirname, "./观书有感2.txt"), (err) => { if (err) { console.log(err); } else { console.log("重命名成功"); } } );// 移动文件夹 rename( path.resolve(__dirname, "./观书有感2.txt"), path.resolve(__dirname, "./test1/观书有感2.txt"), (err) => { if (err) { console.log(err); } else { console.log("重命名成功"); } } );fs.renameSync(oldPath, newPath)renameSync( path.resolve(__dirname, "./test1/观书有感2.txt"), path.resolve(__dirname, "./观书有感.txt") );查看文件状态
fs.stat(path[, options], callback)-
optionsbigint返回的 <fs.Stats> 对象中的数值是否应为bigint。默认值:false。
errstats<fs.Stats>
可以获取文件状态
stat(path.resolve(__dirname, "./观书有感.txt"), (err, data) => { if (err) { console.log(err); } else { console.log(data); } }); // 打印值 Stats { dev: 16777232, mode: 33188, nlink: 1, uid: 501, gid: 20, rdev: 0, blksize: 4096, ino: 86038321, size: 0, blocks: 0, atimeMs: 1756725548336.7957, mtimeMs: 1756725548336.7957, ctimeMs: 1756725548336.7957, birthtimeMs: 1756725548336.7957, atime: 2025-09-01T11:19:08.337Z, mtime: 2025-09-01T11:19:08.337Z, ctime: 2025-09-01T11:19:08.337Z, birthtime: 2025-09-01T11:19:08.337Z }