NodeJS
本文最后更新于:2021年4月8日 下午
基础
- 环境变量(windows系统中变量)
当我们在命令行窗口打开一个文件,或调用一个程序时
系统会首先在当前目录下寻找文件程序,如果找到了则直接打开
如果没有找到则会依次到环境变量path的路径中寻找,直到找到为止
如果没找到则报错
所以我们可以将一些经常需要访问的程序和文件的路径添加到path中,这样我们就可以在任意位置来访问这些文件和程序了 - 进程和线程
进程就是一个一个的工作计划。
线程是计算机中最小的计量单位,负责执行进程中的程序。
JS是单线程,但是在后台拥有一个I/O线程池。
node.js简介
Node.js是一个能够在服务器端运行JavaScript的开放源代码、跨平台JavaScript运行环境。
Node采用Google开发的V8引擎运行js代码,使用事件驱动、非阻塞和异步I/O模型等技术来提高性能,可优化应用程序的传输量和规模。
模块
CommonJS模块
具体例子可见笔记8
包
- CommonJS的包规范由包结构和包描述文件两个部分组成。
包结构:用于组织包中的各种文件
包实际上就是一个压缩文件,解压以后还原为目录。符合规范的目录,应该包含如下文件:
1 |
|
包描述文件:描述包的相关信息,以供外部读取分析
包描述文件用于表达非代码相关的信息,它是一个JSON格式的文件 – package.json,位于包的根目录下,是包的重要组成部分。
NPM
NPM(Node Package Manager)
对于Node而言,NPM帮助其完成了第三方模块的发布、安装和依赖等。借助NPM,Node与第三方模块之间形成了很好的一个生态系统。
指令 | 操作 |
---|---|
npm –v | 查看npm的版本 包名 |
npm r/remove 包名 | 删除一个模块 |
npm i 包名 –save | 安装包并添加到依赖中 |
npm install | 下载当前项目所依赖的包 |
npm i 包名 –g | 全局安装包(全局安装的包一般都是一些工具) |
npm i 文件路径 | 从本地安装 |
npm i 包名 –registry=地址 | 从镜像源安装 |
npm config set registry 地址 | 设置镜像源 |
通过npm下载的包都放到node_modules文件夹中。
通过npm下载的包,直接通过包名引入即可。
node在使用模块名字来引入模块时,它会首先在当前目录的node_modules中寻找是否含有该模块,如果有则直接使用。
如果没有则去上一级目录的node_modules中寻找,如果有则直接使用。
如果没有则再去上一级目录寻找,直到找到为止。
直到找到磁盘的根目录,如果依然没有,则报错。
Buffer(缓冲区)
- Buffer的结构和数组很像,操作的方法也和数组类似
- 数组中不能存储二进制的文件,而buffer就是专门用来存储二进制数据
- 使用buffer不需要引入模块,直接使用即可
- 在buffer中存储的都是二进制数据,但是在显示都是以16进制的形式显示。
buffer中每一个元素的范围是从 00 - ff / 0 - 255 / 00000000 - 11111111
buffer中的一个元素,占用内存一个字节(byte)
- 使用Buffer保存字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18const str = "Hello 前端"
const buf = Buffer.from(str)
// 使用Buffer保存字符串
console.log(buf.length)
// 占用内存的大小
// 12(5+1+3*2)
console.log(str.length)
//字符串的长度
// 8
console.log(buf)
// Buffer(12) [72, 101, 108, 108, 111, 32, 229, 137, 141, 231, 171, 175]
const buf2 = Buffer.from('我是文本')
console.log(buf2.toString()) //我是文本
// buf.toString() 将缓冲区中的数据转换为字符串 - 创建指定大小的Buffer对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22const buf = Buffer.alloc(10)
// 创建一个长度为 10、以零填充的 Buffer
buf[0] = 255
// 会转换成16进制 ff
buf[10] = 1 //不会有改变
// Buffer的大小一旦确定,则不能修改
// Buffer实际上是对底层内存的直接操作
buf[1] = 256 //0
buf[2] = 556 //44
// 会舍弃8位之前的数字
// 556 = 0b1000101100,后8位为0b00101100 = 0x44
consol.log(buf[0]) //255
//只要数字在控制台或页面输出一定是10进制
consol.log(buf[0].toString(2)) //11111111
//转换成别的进制
const buf2 = Buffer.allocUnsafe(10)
// 新创建的 Buffer 的内容是未知的,可能包含敏感数据(不清空数据)
fs(文件系统)
fs 文档
fs(File System),文件系统。简单来说就是通过Node来操作系统中的文件。
服务器的本质就是将本地的文件发送给远程的客户端。
- 要使用fs模块,首先需要对其进行加载
const fs = require("fs")
- fs模块中所有的操作都有两种形式可供选择,同步(Sync)和异步(callback)。
同步文件系统会阻塞程序的执行,也就是除非操作完毕,否则不会向下执行代码。
异步文件系统不会阻塞程序的执行,而是在操作完成时,通过回调函数将结果返回。
同步文件
写入
- 打开文件
1
2
3
4
5
6
7fs.openSync(path[, flags, mode])
- path 要打开文件的路径
- flags 打开文件要做的操作的类型
r 只读的
w 可写的
- mode 设置文件的操作权限,一般不传
该方法会返回一个文件的描述符作为结果,可以通过该描述符来对文件进行各种操作 - 向文件中写入内容
1
2
3
4
5fs.writeSync(fd, string[, position[, encoding]])
- fd 文件的描述符,通过openSync()获取
- string 要写入的内容
- position 写入的起始位置
- encoding 写入的编码,默认utf-8 - 保存并关闭文件
1
2fs.closeSync(fd)
- fd 要关闭文件的描述符
1 |
|
读取
fs.readSync(fd, buffer, [options])
异步文件
写入
- 打开文件
1
2
3
4
5fs.open(path[, flags[, mode]], callback)
异步调用的方法,结果都是通过回调函数的参数返回的
回调函数两个参数
err 错误对象,如果没有错误则为null
fd 文件的描述符 - 异步写入一个文件
1
fs.write(fd, string[, position[, encoding]], callback)
- 关闭文件
1
fs.close(fd, callback)
1 |
|
读取
fs.read(fd, [options,] callback)
简单文件
写入
1 |
|
1 |
|
读取
1 |
|
1 |
|
流式文件
写入
同步、异步、简单文件的写入都不适合大文件的写入,性能较差,容易导致内存溢出。
1 |
|
1 |
|
读取
流式文件读取也适用于一些比较大的文件,可以分多次将文件读取到内容中
1 |
|
1 |
|
1 |
|
其它方法
检查一个文件是否存在
fs.existsSync(path)
1
2
3var isExists = fs.existsSync('a.mp3')
console.log(isExists)
// 存在输出 true,不存在输出 false获取文件信息
fs.Stats类 文档1
2
3fs.stat(path[, options], callback)
fs.statSync(path[, options])
会返回一个对象,这个对象中保存了当前对象状态的相关信息1
2
3
4
5
6
7
8fs.stat('ABC.mp3', function (err, stat) {
/*
isFile() 是否是一个文件
isDirectory() 是否是一个文件夹
*/
// console.log(stat.size)
console.log(stat.isFile())
})删除文件
1
2fs.unlink(path, callback)
fs.unlinkSync(path)1
fs.unlinkSync('hello.txt')
列出文件
1
2fs.readdir(path[, options], callback)
fs.readdirSync(path[, options])1
2
3
4
5
6fs.readdir('.', function (err, files) {
if (!err) {
console.log(files)
}
})
// files是一个字符串数组,每一个元素就是一个文件夹或文件的名字截断文件
1
2fs.truncate(path, len, callback)
fs.truncateSync(path, len)1
2fs.truncateSync('hello2.txt', 10)
截断文件,将文件修改为指定大小建立目录
1
2fs.mkdir(path[, mode], callback)
fs.mkdirSync(path[, mode])1
fs.mkdirSync('hello')
删除目录
1
2fs.rmdir(path, callback)
fs.rmdirSync(path)1
fs.rmdirSync('hello')
重命名文件和目录
1
2
3
4
5fs.rename(oldPath, newPath, callback)
fs.renameSync(oldPath, newPath)
- oldPath 旧路径
- newPath 新路径
- callback 回调函数1
2
3
4
5
6fs.rename('hello3.txt', 'C:/Users/fe/Desktop/555.txt', function (err) {
if (!err) {
console.log('修改成功!')
}
})
// 也可以实现剪切功能监视文件更改写入
1
2
3
4
5
6
7
8
9
10
11fs.watchFile(filename[, options], listener)
- filename 要监视的文件的名字
- options 配置选项
- bigint <boolean> 默认值: false
- persistent <boolean> 默认值: true
- interval <integer> 默认值: 5007 间隔时间
- listener 回调函数,当文件发生变化时,回调函数会执行。有两个参数:
curr 当前文件的状态
prev 修改前文件的状态
这两个对象都是status对象1
2
3
4fs.watchFile('hello4.txt', { interval: 1000 }, function (curr, prev) {
console.log('修改前文件大小:' + prev.size)
console.log('修改后文件大小:' + curr.size)
})
EventEmitter
1 |
|