相关视频
Nodejs 的作用
- 开发服务器应用
- 将我们开发的页面放在服务器端给用户访问
- 开发工具类应用
- vite webpack babel 等工具类的应用
- 开发桌面类应用
- postman figma vscode 都是基于 electron 开发的桌面应用
- electron 是基于 nodejs 开发的
命令结构
- win + r 打开命令行窗口
- 输入 chrome http://baicu.com (命令)
- chrome 为命令名称
- http://baidu.com 为命令参数
命令
d: : 可以切换到 d 盘
cd + 文件夹名称 :进入某个文件
dir : 查看文件夹下有哪些文件
- dir /s : 查看当前文件及所有子文件夹中的所有文件
" . " : 表示当前目录
" .. " : 表示上一级目录
注意
- nodejs 不能使用 BOM 和 DOM 的 API 方法。
- nodejs 中的顶级对象为 global,也可以使用 globalThis 访问顶级对象。
Buffer 缓冲区
类似于 Array 的对象,用于表示固定长度的字节序列。
另一种说法,buffer 就是一段固定长度的内存空间,用于处理二进制数据
特点
- 大小固定且无法调整
- buffer 性能较好,可以直接对计算机内存进行操作
- 每个元素的大小为 1 字节(byte)
创建方式
- alloc : 每次创建 buffer 都会将内存清零
- allocUnsafe : 创建 buffer 时可能会使用 旧数据(缓存数据) ,速度会比 alloc 快。
- from
// Buffer 的创建
// 1. alloc
// > 每次创建Buffer 都会将内存空间都清零。
let buf = Buffer.alloc(10);
console.log(buf); // <Buffer 00 00 00 00 00 00 00 00 00 00>
// 2. allocUnsafe
// > 使用 allocUnsafe 方法创建的 Buffer 可能会携带旧数据(缓存数据)
// > 速度会比 alloc 更快
let buf_2 = Buffer.allocUnsafe(10);
console.log(buf_2); // <Buffer 00 00 00 00 00 00 00 00 00 00>
// 3. form
let buf_3 = Buffer.from("hello");
console.log(buf_3); // <Buffer 68 65 6c 6c 6f>
let buf_4 = Buffer.from([101, 201, 301, 401, 501, 601]);
console.log(buf_4); // <Buffer 65 c9 2d 91 f5 59>
字符串转换
toString()
// 字符串转换
let buf = Buffer.from("hello");
console.log(buf); // <Buffer 68 65 6c 6c 6f> 十六进制
let buf_string = buf.toString();
console.log(buf_string); // hello utf-8 编码规范
// buffer 类似与 array ,所以可以通过下标获取元素
console.log(buf[0]); // 104
console.log(buf); // <Buffer 68 65 6c 6c 6f>
buf[0] = 65;
console.log(buf); // <Buffer 41 65 6c 6c 6f>
console.log(buf.toString()); // Aello
注意点
- 溢出
二进制 buffer 最长只能存 8 位
最大数字只能存到 255 ,超出 8 位的二进制数据会被舍弃。
- 中文
- utf-8 的中文字节,一个中文占 3 个字节。
// 溢出
/*
1. 二进制buffer 最长只能存8位
2. 最大数字只能存到 255 ,超出8位的二进制数据会被舍弃。
*/
let buf = Buffer.from("hello");
buf[0] = 361; // 二进制 0001 0110 1001 => 0110 1001 ( 十六进制为 :69)
console.log(buf); // <Buffer 69 65 6c 6c 6f>
// 中文
let buf_CH = Buffer.from("你好");
console.log(buf_CH); // <Buffer e4 bd a0 e5 a5 bd> 六个字节
fs 模块 (file system 文件系统)
fs.writeFile() 文件写入 (默认异步写入)
- 引入 fs 模块
- 调用 writeFile()
如果文件不存在 则会创建一个新文件。
- node 运行 该 js 文件
// 引入 fs 模块
let fs = require("fs");
// 调用 writeFile 向某个文件中写入内容 (如果文件不存在 则会创建一个新文件。)
fs.writeFile("./座右铭.txt", "他日若遂凌云志,敢笑黄巢不丈夫。", (err) => {
if (!err) console.log("成功运行");
else console.log("报错信息", err);
});
console.log("js主线程输出");
// 由于writeFile是异步任务,所以 会先输出 "js主线程输出" 后输出 "成功运行"
fs.writeFileSync()
该方法没有回调函数
fs.writeFileSync("./data.txt", "应是天仙狂醉,醉把白云揉碎。");
appenFile() 追加写入
- writeFile() 第三个参数写为 {flag:‘a’}
- 使用 appendFile() 函数,可以实现文件的追加写入功能 (异步)
- 使用 appendFileSync() 函数, 也可以实现文件的追加写入功能 (同步)
小技巧:
\r\n 可以实现换行功能
/**
* 文件追加写入:
* 1. writeFile() 第三个参数写为 {flag:'a'}
* 2. 使用 appendFile() 函数,可以实现文件的追加写入功能 (异步)
* 3. 使用 appendFileSync() 函数, 也可以实现文件的追加写入功能 (同步)
*
* \r\n 可以实现换行功能
*/
let fs = require("fs");
// 方法一:
fs.writeFile(
"./座右铭.txt",
"\r天生我材必有用,千金散尽还复来.\n红豆生南国,春来发几枝",
{ flag: "a" },
(error) => {
if (error) {
console.log("写入失败!");
return false;
}
console.log("写入成功");
}
);
// 方法二:
fs.appendFile("./座右铭.txt", "\r他日若遂凌云志,敢笑黄巢不丈夫.", (error) => {
if (error) {
console.log("写入失败!");
return false;
}
console.log("写入成功");
});
// 方法三:
fs.appendFileSync(
"./座右铭.txt",
"\n南村群童欺我老无力,忍能对面为盗贼.",
(error) => {
if (error) {
console.log("写入失败!");
return false;
}
console.log("写入成功");
}
);
文件流式写入 createWriteStream()
优点:
- 相比文件写入,流式写入过程中,写入通道不会关闭 ,可持续写入
- 写入速度较快,同时可以写入大文件
// 导入 fs
let fs = require("fs");
// 创建 流式写入对象
let ws = fs.createWriteStream("./唐诗三百首.txt");
// write 写入数据
ws.write("红豆生南国,\r\n");
ws.write("春来发几枝.\r\n");
ws.write("愿君多采撷,\r\n");
ws.write("此物最相思.\r\n");
// 关闭通道 (注意: close() 忘记调用也没关系,系统在文件写入成功后会自动关闭)
ws.close(); // 可调用也可不调用.
文件读取 readFile(), readFileSync()
readFileSync: 同步读取文件,顺序会快于 readFile.
// 导入 fs
let fs = require("fs");
// 文件读取:方式一
fs.readFile("./唐诗三百首.txt", function (err, data) {
if (err) {
console.log(err);
return;
}
// 如果直接打印 data, 打印的是 buffer 对象
// console.log(data);
// 文件读取成功, 打印文件内容 ,toString() 将buffer对象 转成字符串
console.log("readFile", data.toString());
});
// 文件读取:方式二 (同步读取,下面的打印会比上面的打印结果快)
let syncData = fs.readFileSync("./唐诗三百首.txt");
console.log("syncData", syncData.toString());
文件流式读取 createReadStream()
// 导入 fs
let fs = require("fs");
// 流式文件读取
let rs = fs.createReadStream("./巴以.mp4");
// 绑定 data 事件
rs.on("data", function (chunk) {
// 打印读取到的流式内容,内容为 buffer对象
console.log("chunk", chunk);
// 打印流式内容的长度
console.log("chunk", chunk.length);
// 注意: 视频内容读取到的 buffer 不能使用 toString() 转换,否则内容会乱码
// console.log(chunk.toString());
});
// 可选事件
rs.on("end", function () {
console.log("读取完成: 读取完成后的回调函数.(注意:没有 chunk数据流)");
});
练习(视频文件复制)
方式一 : readFileSync(), writeFileSync()
通过 readFileSync() 同步读取文件,通过 writeFileSync() 同步写入文件.
缺点: 文件内容大时,效率低.(
不推荐
)
- 这种方式是将 整个文件全部读取到内存中,然后写入.
// 导入 fs
let fs = require("fs");
let process = require("process");
// 文件读取
let data = fs.readFileSync("./巴以.mp4");
// 文件写入
fs.writeFileSync("./巴以2.mp4", data);
console.log(process.memoryUsage()); // rss : 103751680 => 98.94MB
方式二: creadReadStream(), createWriteStream()
通过 createReadStream() 创建流式读取对象,通过 createWriteStream() 创建流式写入对象.
优点: 效率高.(
推荐
)
- 流式读取,分批次读取 ,一次最多读取 64kb,然后写入.
// 导入 fs
let fs = require("fs");
let process = require("process");
// 创建读取流对象
let rs = fs.createReadStream("./巴以.mp4");
// 写入流对象
let ws = fs.createWriteStream("./巴以3.mp4");
rs.on("data", (chunk) => {
ws.write(chunk);
});
rs.on("end", () => {
console.log(process.memoryUsage()); // rss : 38637568 => 36.84MB
});
效率验证
可通过引入,process 模块,获取当前进程的内存占用情况.进行比较
- 引入 process 模块
- process.memoryUsage() 获取当前进程的内存占用情况
- 打印结果只需要查看 rss 字段即可(表示内存总占用大小)