node.js ---文件读写(FS模块)
此文章是根据尚硅谷教学视频而总结的一篇笔记, 原视频: 【尚硅谷Node.js零基础视频教程,nodejs新手到高手】 https://www.bilibili.com/video/BV1gM411W7ex/?share_source=copy_web&vd_source=7336f6dae330ae9637a6a01932103639
Buffer 缓冲区
概念
是一个类似于数组的对象, 用于表示固定长度的字节序列
本质是一段内存空间, 专门用来处理二进制数据
大小固定且无法调整
性能较好, 可以直接对计算机内存进行操作
每个元素的大小为 8 bit (1 byte)
创建 Buffer
1. Buffer.alloc(size)
let buf = Buffer.alloc(10);
console.log(buf); // <Buffer 00 00 00 00>
let buf1 = Buffer.allocUnsafe(10); // 与 alloc 类似, 但不保证填充 0, 因此速度更快, 但使用时要注意
console.log(buf1); // <Buffer 00 00 00 00>
3. Buffer.from(Array/String)
let buf1 = Buffer.from([1, 2, 3]);
console.log(buf1); // <Buffer 01 02 03>
// 若数字只为0或1, 直接默认为二进制, 若为其他数字, 会转为二进制, 但精度会丢失(大小不够, 只能存储1byte, 舍弃二进制高位)
// 直接转为二进制存储, 显示16进制
let buf2 = Buffer.from("hello");
console.log(buf2); // <Buffer 68 65 6c 6c 6f>
// 存储的的是对应字符的 ASCII 码, 二进制存储, 显示16进制
Buffer 转字符串
let buf = Buffer.from([105, 108, 111, 118, 101, 121, 111, 117]);
console.log(buf.toString()); // "iloveyou"
操作 Buffer
可以通过 []
来读写元素(类似于数组)
let buf = Buffer.from("hello");
console.log(buf[0]); // 104
console.log(buf[0].toString(2)); // "1101000"
buf[0] = 101;
console.log(buf.toString()); // "eello"
path模块
const path = require('path');path.resolve("__dirname", "test.txt")
// 方法用于将多个路径片段组合成一个完整路径。
// 建议第一个路径为绝对路径,后续的路径片段会被添加到这个绝对路径上。
// __filename - 当前模块文件的绝对路径, __dirname - 当前模块文件所在的目录的绝对路径。path.sep
// 属性用于获取当前平台的路径分隔符。
// 在 Windows 上为 "\", 在 Linux/Unix 上为 "/"。path.parse("path/to/file.txt")
// 方法用于将一个路径字符串解析为对象。
// 返回的对象包含以下属性:
// dir - 目录名
// root - 根目录
// base - 文件名
// ext - 文件扩展名
// name - 文件名(不包含扩展名)path.basename("path/to/file.txt") // 返回文件名
path.dirname("path/to/file.txt") // 返回目录名
path.extname("path/to/file.txt") // 返回文件扩展名
fs 模块
fs 模块是 Node.js 中用于操作文件系统的核心模块。
写入文件
普通写入
const fs = require("fs"); // 以后的实例默认导入 fs 模块fs.writeFile("./test.txt", "Hello Node.js", (err) => {if (err) {console.log("写入失败");}console.log("文件写入成功!");
});
// 同步写入
fs.writeFileSync("./data.txt", "Hello Node.js");
追加写入
// 采用同步的写法
fs.appendFileSync("./test.txt", "追加写入");
// 可使用try...catch...处理写入失败的情况
流式写入
更适合写入频次较高的场景
const ws = fs.createWriteStream("./test.txt");
ws.write("Hello javaScript");
ws.write("Hello Node.js"); // 同步写法
ws.close();
写入文件的使用场景
- 下载文件
- 安装软件
- 保存程序日志, 如 Git
- 编辑器保存文件
- 视频录制
当需要持久化存储数据时,建议使用文件写入。
读取文件
普通读取
fs.readFile("./test.txt", (err, data) => {if (err) {console.log("读取失败");return;}console.log("读取成功", data.toString());
});
同步读取
try {const data = fs.readFileSync("./test.txt");console.log(data.toString());
}catch (err) {console.log("读取失败", err);
}
读取流式文件
const rs = fs.createReadStream("./test.txt");
rs.on("data", (chunk) => {console.log(chunk.toString()); // 每次读取64kb数据
});rs.on("end", () => {console.log("文件读取完毕");
}); // 文件读取完毕
读取文件的使用场景
- 电脑开机
- 程序运行
- 编辑器打开文件
- Git 查看日志
- 上传文件
- 查看聊天记录
更改文件名/移动文件
fs.rename("./test.txt", "./test2.txt", (err) => {if (err) {console.log("重命名失败", err);return;}
});
删除文件
fs.unlink("./test2.txt", (err) => {if (err) {console.log("删除失败", err);return;}console.log("文件删除成功");
});
fs.rm("./test", (err) => {if (err) {console.log("删除失败", err);return;}console.log("删除成功");
});
创建文件夹
// 递归创建
fs.mkdir("./test/a/b/c", { recursive: true }, (err) => {if (err) {console.log("创建失败", err);return;}console.log("创建成功");
});
读取文件夹资源
fs.readdir("./test", (err, files) => {if (err) {console.log("读取失败", err);return;}console.log("读取成功", files);
});
删除文件夹
// 非递归删除, 只能删除空文件夹
fs.rmdir("./test", (err) => {if (err) {console.log("删除失败", err);return;}console.log("删除成功");
});
// 递归删除, 可删除非空文件夹
fs.rm("./test", { recursive: true }, (err) => {if (err) {console.log("删除失败", err);return;}console.log("删除成功");
});
查看资源状态
fs.stat("./test.txt", (err, stats) => {if (err) {console.log("获取失败", err);return;}console.log(stats);console.log("是否是文件:", stats.isFile());console.log("是否是目录:", stats.isDirectory());
});
相对路径
参照的是命令行的工作目录
推荐使用绝对路径
console.log(__dirname); // 当前文件所在目录的绝对路径
fs.readFileSync(__dirname + “/test.txt”); // 读取当前文件所在目录下的 test.txt 文件