1.Node介绍
1.1Node是什么?
Node.js is an open-source, cross-platform JavaScript runtime environment.
翻译:Node.is 是一个开源的,跨平台的 JavaScript 运行环境.
通俗来讲: Node.js 就是一款应用程序,是一款软件,它可以运行 JavaScript
1.2Node.js的作用
1.开发服务器应用
2.开发工具类应用
3.开发桌面端应用
1.3认识命令
1.3.1命令的结构
chrome
http://www.baidu.com
http://bilibili.com
命令名称 参数 1 参数 2
1.3.2常用命令
命令行如何查看『 D:/Program Files 』里的内容 ?
在 Windows 系统中,可以通过命令行(CMD 或 PowerShell)使用 dir
命令查看指定目录的内容。以下是具体步骤:
方法 1:直接列出目录内容
- 打开命令行:
- 按
Win + R
,输入cmd
或powershell
,回车。
- 按
- 输入命令:
dir "D:\Program Files"
dir
:列出目录内容。"D:\Program Files"
:路径包含空格时需用引号包裹(Windows 路径通常用反斜杠\
)。
方法 2:先切换盘符再查看
- 切换到 D 盘:
D:
- 进入目录并查看:
cd "Program Files" # 进入目录 dir # 列出当前目录内容
可选参数(按需使用)
- 显示隐藏文件/系统文件:
dir /a
- 显示详细信息(修改时间、大小等):
dir /w
1.3.3命令行常用操作
说明 | 操作 |
---|---|
切换盘符 | C: D: |
切换工作目录 | cd |
查看目录文件 | dir |
1.4注意
Node.js 中不能使用 BOM 和 DOM 的 API
- Node.js 中不能使用 BOM 和 DOM 的 API,可以使用 console 和定时器 API。
- Node.js 中的顶级对象为 global,也可以用 globalThis 访问顶级对象。
2.Buffer
Buffer 中文译为『缓冲区』,是一个类似于 Array 的对象,用于表示固定长度的字节序列。
换句话说,Buffer 就是一段固定长度的内存空间,用于处理二进制数据
1.概念
Buffer 是一个类似于数组的 对象,用于表示固定长度的字节序列Buffer 本质是一段内存空间,专门用来处理 二进制数据 。
2.特点
1.Buffer 大小固定且无法调整
2.Buffer 性能较好,可以直接对计算机内存进行操作
3.每个元素的大小为1字节(byte)。
3.使用
在 Node.js 中,Buffer
是一个用于处理二进制数据的全局对象,它可以方便地进行数据的存储和操作。以下是关于 Buffer
的创建、与字符串的转化以及读写操作的详细介绍:
3-1. 创建 Buffer
Buffer
有多种创建方式:
- 通过长度创建:创建一个指定长度的
Buffer
,初始内容为随机值。
//Buffer.alloc(size)
//创建一个指定大小且填充零的安全 Buffer
const buf = Buffer.alloc(10); // 创建一个长度为 10 的 Buffer
console.log(buf);
- 通过数组创建:使用一个包含数字的数组来创建
Buffer
,每个数字表示一个字节。
//Buffer.allocUnsafe(size);创建指定大小的 Buffer,但不初始化内存
const buf = Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f]); // 创建一个包含 'hello' 字节的 Buffer
console.log(buf);
- 通过字符串创建:从一个字符串创建
Buffer
,可以指定字符编码。
const buf = Buffer.from('你好', 'utf8'); // 创建一个包含 '你好' 的 Buffer,编码为 utf8
console.log(buf);
4.** 从其他 Buffer 复制**
Buffer.from(buffer)
复制现有 Buffer 的数据。
const buf5 = Buffer.from(buf3);
console.log(buf5); // <Buffer 48 65 6c 6c 6f>
3-2. Buffer 与字符串的转化
- Buffer 转字符串:使用
toString()
方法将Buffer
转换为字符串,可以指定字符编码。
buf.toString([encoding])
1.
const buf = Buffer.from('你好', 'utf8');
const str = buf.toString('utf8');
console.log(str); // 输出 '你好'
2.
const buf = Buffer.from("你好");
console.log(buf.toString()); // "你好"(UTF-8)
console.log(buf.toString("hex")); // "e4bda0e5a5bd"(十六进制)
console.log(buf.toString("base64")); // "5L2g5aW9"(Base64)
- 字符串转 Buffer:使用
Buffer.from()
方法将字符串转换为Buffer
,同样可以指定字符编码1。
Buffer.from(string, [encoding])
const str = '你好';
const buf = Buffer.from(str, 'utf8');
console.log(buf);
const bufUtf8 = Buffer.from("你好", "utf8"); // <Buffer e4 bd a0 e5 a5 bd>
const bufHex = Buffer.from("e4bda0e5a5bd", "hex"); // 同 bufUtf8
const bufBase64 = Buffer.from("5L2g5aW9", "base64"); // 同 bufUtf8
3-3. Buffer 的读写
- 写入 Buffer:使用
write()
方法将字符串写入Buffer
。
const buf = Buffer.alloc(256);
const str = 'Hello, Buffer!';
const byteLength = buf.write(str, 0, 'utf8'); // 从索引 0 开始写入字符串
console.log(`写入的字节数: ${byteLength}`);
console.log(buf.slice(0, byteLength)); // 输出写入的内容
运行结果:
//通过索引写入字节,直接修改 Buffer 的索引值
const buf = Buffer.alloc(3);
buf[0] = 0x41; // 'A'
buf[1] = 0x42; // 'B'
buf[2] = 0x43; // 'C'
console.log(buf.toString()); // "ABC"
- 读取 Buffer:从
Buffer
中读取数据。
const buf = Buffer.from('Hello, Buffer!', 'utf8');
const str = buf.toString('utf8', 0, 5); // 从索引 0 读取到索引 5(不包括 5)
console.log(str); // 输出 'Hello'
//通过索引读取字节,直接访问 Buffer 的索引
const buf = Buffer.from("ABC");
console.log(buf[0]); // 65(ASCII码的'A')
console.log(buf[1]); // 66('B')
- 读取指定字节:可以直接访问
Buffer
的每个字节。
const buf = Buffer.from('abc');
for (let i = 0; i < buf.length; i++) {
console.log(buf[i]); // 输出每个字节的数值
}
遍历 Buffer
使用 for…of 或 forEach 遍历每个字节:
const buf = Buffer.from("Node.js");
for (const byte of buf) {
console.log(byte); // 78 111 100 101 46 106 115
}
2.fs模块
Node.js 中的 fs
模块(File System)是用于操作文件系统的核心模块,提供了同步和异步的 API。以下是该模块的核心知识点和示例:
核心功能
- 文件操作:读取、写入、追加、删除文件。
- 目录操作:创建、读取、删除目录。
- 文件信息:获取文件状态(如大小、创建时间)。
- 流操作:通过流(Stream)处理大文件。
- 权限管理:修改文件权限或所有者。
常用方法速查
方法名 | 作用 | 同步版本 |
---|---|---|
readFile | 读取文件内容 | readFileSync |
writeFile | 写入文件内容 | writeFileSync |
appendFile | 追加内容到文件末尾 | appendFileSync |
unlink | 删除文件 | unlinkSync |
mkdir | 创建目录 | mkdirSync |
readdir | 读取目录内容 | readdirSync |
rmdir | 删除空目录 | rmdirSync |
stat | 获取文件/目录状态信息 | statSync |
rename | 重命名文件/目录 | renameSync |
copyFile | 复制文件 | copyFileSync |
watch | 监听文件/目录变化 | - |
引入fs模块
在Node.js中,使用fs
模块前需要先引入:
const fs = require('fs');
写入文件
文本写入
const fs = require('fs'); fs.writeFile('./text1.txt',
'三人行,必有我师', err => {
// err 为写入失败:错误对象 写入成功:null
if (err) {
console.log(err);
}else {
console.log('写入成功');
}
});
1.writeFile
异步写入
const fs = require('fs');
const content = '这是要写入文件的内容';
fs.writeFile('.\output.txt', content, err => {
if (err) {
console.error(err);
return;
}
console.log('文件写入成功');
});
fs.writeFile
用于写入文件。第一个参数是文件名,第二个参数是要写入的内容,回调函数中err
表示错误信息,如果写入成功则err
为null
。
2.writeFileSync
同步写入
const fs = require('fs');
const content = '同步写入的内容';
fs.writeFileSync('./text2.txt', content);
console.log('同步写入成功');
3.二进制写入
const fs = require('fs');
const buffer = Buffer.from('Hello Node.js');
fs.writeFile('./binary.txt', buffer, (err) => {
if (err) {
console.log(err);
} else {
console.log('二进制写入成功');
}
});
4.appendFile/appendFileSync
追加写入
const fs = require('fs');
fs.appendFile('./text1.txt', '青山不改绿水长流', (err) => {
if (err) {
console.log(err);
} else {
console.log('写入成功');
}
});
5.createWriteStream
流式写入
const fs = require('fs');
//创建写入流
const ws = fs.createWriteStream('./text.txt');
//写入数据
ws.write('半亩花田一鉴开\r\n');
ws.write('一日三秋,春暖花开\r\n');
ws.write('一蓑烟雨任平生\r\n');
ws.write('一声叹息,一壶酒,一瓢饮\r\n');
//关闭通道
ws.close();
fs.writeFileSync('./text2.txt', data);
与
fs.writeFileSync('text2.txt', data);
区别:./text2.txt
明确使用了当前目录(.)
这个相对路径标识符。它清晰地表明,要在当前执行脚本所在的目录下查找或创建 text2.txt 文件。
text2.txt
同样是一个相对路径,但没有明确指定相对的起始位置。在 Node.js 中,这种写法默认也是相对于当前工作目录,即执行
node 命令时所在的目录 。
读取文件
- readFile异步读取
fs.readFile(path[, options], callback)
path :文件路径
options: 选项配置
callback :回调函数
返回值: undefine
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
fs.readFile('example.txt', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
上述代码中,fs.readFile
用于读取文件。第一个参数是文件名,第二个参数指定了文件的编码格式(这里是utf8
),回调函数接收两个参数,err
表示错误信息,如果读取成功则err
为null
,data
为读取到的文件内容。
2. readFileSync
同步读取
语法:
fs.readFileSync(path[, options])
参数说明:
path :文件路径
options :选项配置
返回值: string | Buffer
const fs = require('fs');
const data = fs.readFileSync('example.txt', 'utf8');
console.log(data);
const data = fs.readFileSync('example.txt');
3.createReadStream
流式读取
语法:fs.createReadStream(path[, options])
参数说明:
path: 文件路径
options :选项配置(可选)
返回值: Object
//创建读取流对象
let rs = fs.createReadStream('./content.txt');
//每次取出 64k 数据后执行一次 data 回调
rs.on('data', data => {
console.log(data);
console.log(data.length);
});
//读取完毕后, 执行 end 回调
rs.on('end', () => {
console.log('读取完成')
})
在Node.js中,文件的移动和重命名操作都可以使用fs.rename()
或 fs.renameSync()
方法来实现。因为移动文件本质上就是将文件从一个路径移动到另一个路径,这一过程与重命名类似,只是目标路径可能在不同的目录下。
以下是使用 fs
模块进行文件移动和重命名的示例:
文件移动与重命名
fs.unlink(path, callback) fs.unlinkSync(path)
1. 异步重命名/移动文件
const fs = require('fs');
// 重命名文件(在同一目录下,只是文件名改变)
const oldPath = 'oldFileName.txt';
const newPath = 'newFileName.txt';
fs.rename(oldPath, newPath, (err) => {
if (err) {
console.error('重命名文件时发生错误:', err);
return;
}
console.log('文件重命名成功');
});
// 移动文件到不同目录
const sourcePath = 'fileToMove.txt';
const targetPath = 'newDirectory/fileToMove.txt';
fs.rename(sourcePath, targetPath, (err) => {
if (err) {
console.error('移动文件时发生错误:', err);
return;
}
console.log('文件移动成功');
});
2. 同步重命名/移动文件
const fs = require('fs');
// 重命名文件(在同一目录下,只是文件名改变)
const oldPath = 'oldFileName.txt';
const newPath = 'newFileName.txt';
try {
fs.renameSync(oldPath, newPath);
console.log('文件重命名成功');
} catch (err) {
console.error('重命名文件时发生错误:', err);
}
// 移动文件到不同目录
const sourcePath = 'fileToMove.txt';
const targetPath = 'newDirectory/fileToMove.txt';
try {
fs.renameSync(sourcePath, targetPath);
console.log('文件移动成功');
} catch (err) {
console.error('移动文件时发生错误:', err);
}
其他常用方法
- ⑴创建目录(文件夹):
fs.mkdir
(异步)和fs.mkdirSync
(同步)
fs.mkdir(path[, options], callback) fs.mkdirSync(path[, options])
// 异步创建目录
fs.mkdir('new-folder', err => {
if (err) {
console.error(err);
return;
}
console.log('目录创建成功');
});
// 同步创建目录
try {
fs.mkdirSync('sync-new-folder');
console.log('同步目录创建成功');
} catch (err) {
console.error(err);
}
- ⑵删除文件:
fs. rmdir 或fs.rmdirSync(同步)
来删除文件夹
fs.rmdir(path[, options], callback) fs.rmdirSync(path[, options])
//异步删除文件夹
fs.rmdir('./page', err => {
if(err) throw err;
console.log('删除成功');
});
//异步递归删除文件夹
fs.rmdir('./1', {recursive: true}, err => {
if(err) {
console.log(err);
}
console.log('递归删除')
});
//同步递归删除文件夹
fs.rmdirSync('./x', {recursive: true})
- ⑶读取目录内容:
fs.readdir
(异步)和fs.readdirSync
(同步)
fs.readdir(path[, options], callback) fs.readdirSync(path[, options])
// 异步读取目录内容
fs.readdir('folder', (err, files) => {
if (err) {
console.error(err);
return;
}
console.log(files);
});
// 同步读取目录内容
try {
const files = fs.readdirSync('sync-folder');
console.log(files);
} catch (err) {
console.error(err);
}
关键特性
1. 同步 vs 异步
- 异步方法:通过回调函数处理结果,避免阻塞主线程。
const fs = require('fs'); // 异步读取文件(推荐) fs.readFile('file.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); });
- 同步方法:方法名以
Sync
结尾,直接返回结果,但会阻塞代码执行。const data = fs.readFileSync('file.txt', 'utf8'); console.log(data);
2. 流(Stream)处理
适合大文件操作,避免一次性加载到内存:
const fs = require('fs');
const readStream = fs.createReadStream('large-file.txt');
const writeStream = fs.createWriteStream('copy-large-file.txt');
readStream.pipe(writeStream); // 通过管道传输数据
3. 递归目录操作
- 创建多级目录(
recursive: true
):fs.mkdir('parent/child/grandchild', { recursive: true }, (err) => { if (err) throw err; });
- 删除非空目录(需第三方库如
rimraf
或 Node.js 14.14.0+ 的rm
):fs.rm('directory', { recursive: true }, (err) => { /* ... */ });
实用代码示例
1. 读取文件内容
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data); // 输出文本内容
});
2. 写入文件
fs.writeFile('new-file.txt', 'Hello World', (err) => {
if (err) throw err;
console.log('文件已保存!');
});
3. 检查文件是否存在(推荐方式)
fs.access('file.txt', fs.constants.F_OK, (err) => {
console.log(err ? '文件不存在' : '文件存在');
});
4. 获取文件状态
fs.stat('file.txt', (err, stats) => {
if (err) throw err;
console.log(`文件大小:${stats.size} 字节`);
console.log(`创建时间:${stats.birthtime}`);
});
通过 fs
模块,你可以高效地管理 Node.js 中的文件系统操作。如果需要更高级的功能(如文件监视、递归删除),可结合第三方库(如 chokidar
、rimraf
)使用。
相对路径问题
相对路径
./座右铭.txt
当前目录下的座右铭.txt座右铭.txt
等效于上面的写法../座右铭.txt
当前目录的上一级目录中的座右铭.txt
绝对路径
D:/Program Files
windows 系统下的绝对路径/usr/bin
Linux 系统下的绝对路径
在 Node.js 中,fs.writeFileSync('./text2.txt', data)
和 fs.writeFileSync('text2.txt', data)
的区别主要在于路径的显式性,但两者实际效果完全相同。以下是详细解析:
const fs = require('fs');
// 两种写法等价,文件均写入到 /project/text2.txt
fs.writeFileSync('./text2.txt', 'Hello'); // 显式写法
fs.writeFileSync('text2.txt', 'Hello'); // 隐式写法
总结
写法 | 路径含义 | 适用场景 |
---|---|---|
'./text2.txt' | 显式当前目录 | 强调文件位置,提高代码可读性 |
'text2.txt' | 隐式当前目录 | 简洁写法,适合熟悉路径规则 |
path.join(__dirname, 'text2.txt') | 基于脚本目录的绝对路径 | 避免工作目录陷阱,推荐使用 |
查看资源状态
fs.stat(path[, options], callback) fs.statSync(path[, options])
//异步获取状态
fs.stat('./data.txt', (err, data) => {
if(err) throw err;
console.log(data);
});
//同步获取状态
let data = fs.statSync('./data.txt');
_
_dirname
**__dirname**
与 require
类似,都是 Node.js 环境中的’全局’变量
__dirname
保存着当前文件所在目录的绝对路径,可以使用 __dirname 与文件名拼接成绝对路径.
let data = fs.readFileSync(__dirname + '/data.txt');
console.log(data);
常用编码:utf8(默认)、ascii、base64、hex、latin1 等。
注意:部分编码(如 utf8)可能需要多字节表示一个字符。 ↩︎