一、什么是node.js?
Node.js是一个开源的,跨平台的js运行环境。
是一个应用程序,是一款软件。
2、作用
1)开发服务器应用
node.js运行在服务器,是网页能够被所有人访问
2)开发工具类应用
Webpack、Vite、Babel
3)开发桌面端应用
3、下载并安装node.js
LTS:长期支持版本
Current:当前最新版本
node -v :查看node的版本
4、node使用注意事项
console.log(window)
console.log(history)
console.log(document)
let xhr = new XMLHttpRequst()会报错
5、Buffer(缓冲器)
1)Buffer的创建
// 1.alloc
// 初始化为0
let buffer = Buffer.alloc(10)
// console.log(buffer) //<Buffer 00 00 00 00 00 00 00 00 00 00>
// 2.allocUnsafe
// 将之前的元素和之后的元素都使用10进制进行输出
let buf_2 = Buffer.allocUnsafe(10000)
// console.log(buf_2) // <Buffer 00 00 00 00 00 00 00 00 19 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19 00 04 00 04 00 05 00 04 00 04 00 0f 0f 0f 05 d0 6d 82 0d 01 00 00 00 02 00 ... >
// 3.from
// 将传入的参数转换为10进制输出
let buf_3 = Buffer.from('hello')
let buf_4 = Buffer.from([105, 108, 111, 101, 121, 111, 117])
console.log(buf_4) //<Buffer 69 6c 6f 65 79 6f 75>
2)Buffer与字符串的转化
// buffer 与 字符串的转换
let buf_4 = Buffer.from([105, 108, 111, 118, 101, 121, 111, 117])
// console.log(buf_4.toString()) // utf-8编码形式 iloveyou
// [] 对元素进行读取和写入
let buf = Buffer.from('hello')
console.log(buf[0])// 104 十六进制
console.log(buf[0].toString(2)) // 1101000 二进制
buf[0] = 95
console.log(buf.toString())
// 溢出
let buf = Buffer.from('hello')
buf[0] = 361 //舍弃高位的数字 0001 0110 1001 =》 舍弃高位后 0110 1001
// 中文 utf-8中 中文是占三个字节的
let buf = Buffer.from('你好')
console.log(buf)
6、计算机的组成
7、程序的基本运行
程序一般保存在硬盘中,软件安装的过程就是将程序写入硬盘的过程。
程序在运行时会加载进入内存,然后由cpu读取并执行程序。
![](https://i-blog.csdnimg.cn/blog_migrate/c8f4e4a5bf8c8730f12c8a4da6f62ea1.png)
8、进程和线程
进程:一次程序运行的过程。 例如:启动qq就是一个进程, 启动微信就是另一个进程
线程:是一个进程中执行的一个执行流 ,一个线程是属于某个进程的。 例如:蜜雪冰城是一个进程,内部的员工在干不同的工作,那他们就是线程。
二、fs模块-file system
1、写入文件 - writeFile
为什么使用fs写入:实现自动化修改内容。
/**
* 新建一个文件,座右铭.txt 写入:三人行,则必有我师焉!
* */
//1、导入fs模块
const fs = require('fs')
// 2、写入文件
fs.writeFile('./座右铭.txt', "三人行,则必有我师焉", err =>{
// err 写入失败:错误对象, 写入成功:null
if(err){
console.log(err)
return
}
console.log('写入成功')
})
2、同步和异步
fs异步写入:
输出结果:
2
“写入成功”
/**
* 新建一个文件,座右铭.txt 写入:三人行,则必有我师焉!
* */
//1、导入fs模块
const fs = require('fs')
// 2、写入文件
fs.writeFile('./座右铭.txt', "三人行,则必有我师焉", err =>{
// err 写入失败:错误对象, 写入成功:null
if(err){
console.log(err)
return
}
console.log('写入成功') //在输出“写入成功”
})
console.log(1+1) //先输出2
fs同步写入:
fs.writeFileSync('./data/txt', 'test')
3、追加写入-appendFile / appendFileSync
使用场景:1、不停往文件中追加内容;例如日志 2、记录用户的访问
// 1、引入 fs 模块
const fs = require('fs')
// 2、调用 appendFile
fs.appendFile('./座右铭.txt', '择其善者而从之,不善者而改之', err =>{
// 判断
if(err){
console.log('写入失败')
return
}
console.log('追加写入成功')
})
fs.appendFileSync('./座右铭.txt', '\r\n温故知新,可以为师矣')
// writeFile 实现追加写入
fs.writeFile('./座右铭.txt', 'love love love', {flag:'a'},err =>{
if(err){
console.log('写入失败')
return
}
console.log('写入成功')
})
4、fs流式写入 - createWriteStream(path[, option])
流式写入 和 writeFile写入的区别是:
流式写入是建立一次通道之后可以持续输入;
writeFile是需要写入一次内容,建立一次链接通道。
5、文件写入的使用场景
需要持久化保存数据==》 文件写入
1)下载文件
2)安装文件
3)保存程序日志, 比如git
4)编辑器保存文件
5)视频录制
6、文件的读取 - readFile/ readFileSync
// 1、引入 fs 模块
const fs = require('fs')
// 2、异步读取,
fs.readFile('./观书有感.txt', (err, data) =>{
if(err){
console.log('读取失败')
return
}
console.log(data.toString())// data是一个buffer对象,所有要进行toString转换
})
// 3、同步读取
let data = fs.readFileSync('./观书有感.txt')
console.log(data.toString())
7、文件读取的应用场景
8、文件流式读取- createReadStream
流式读取:一块一块的读取文件
好处?
// 1、引入 fs 模块
const fs = require('fs')
// 2、创建读取流对象
const rs = fs.createReadStream('../资料/笑看风云.mp4')
// 3、绑定 data 事件, chunk 块儿 大块儿
rs.on('data', chunk => {
console.log(chunk) //输出为buffer
console.log(chunk.length) // 65536 字节=》 64kb
console.log(chunk.toString()) // 65536字节 => 64KB
})
// 4、end 可选事件
rs.on('end', () =>{
console.log('读取完成')
})
9、练习:文件的复制
/**
* 需求:
* 复制【资料】文件夹下的【笑看风云.mp4】
* */
const fs = require('fs')
const process = require('process')
// 方式1: readFile
//读取文件内容
let data = fs.readFileSync('../资料/笑看风云.mp4')
// 写入文件
fs.writeFileSync('../资料/笑看风云-2.mp4', data)
console.log(process.memoryUsage()) //rss 110710784 字节 105MB
// 方式2: 流式操作
// 创建读取流对象
const rs = fs.createReadStream('../资料/笑看风云.mp4')
// 创建写入流对象
const ws = fs.createWriteStream('../资料/笑看风云-3.mp4')
// // 绑定 data 事件
// rs.on('data', chunk => {
// ws.write(chunk)
// })
// rs.on('end', ()=>{
// console.log(process.memoryUsage()) // 43106304 => 41M
// })
// 简便方法实现复制 pipe:管道 将读取流 通向 写入流
rs.pipe(ws)
10、文件的重命名和移动 - rename
// 引入 fs 模块
const fs = require('fs')
// 调用 rename 方法
fs.rename('./座右铭.txt', './论语.txt', err => {
if(err){
console.log('操作失败~')
return
}
console.log('操作成功')
})
// 文件的移动
fs.rename('./data.txt', '../资料/data.txt', err =>{
if(err){
console.log('操作失败~')
return
}
console.log('操作成功')
})
11、文件删除- unlink / rm
// 导入 fs 模块
const fs = require('fs')
// 方法1: 调用 unlink 方法 同步方法: unlinkSync
fs.unlink('./观书有感.txt', err =>{
if(err){
console.log('删除失败~')
return
}
console.log('删除成功')
})
// 方法2: 调用 rm 方法 14.4. 同步方法: rmSync
fs.rm('./论语.txt', err =>{
if(err){
console.log('删除失败~')
return
}
console.log('删除成功')
})
12、文件夹操作-创建- mkdir / mkdirSync-读取-readdir -删除- rm/rmdir
//导入 fs 模块
const fs = require('fs')
// 方法1: 创建文件夹 mk make 制作 dir directory 文件夹
fs.mkdir('./html', err =>{
if(err){
console.log('创建失败~~')
return
}
console.log('创建成功')
})
// 方法2: 递归创建
fs.mkdir('./a/b/c',{recursive: true}, err => {
if(err){
console.log('创建失败~~~')
return
}
console.log('创建成功')
})
// 读取文件夹 read 读取 dir directory 文件夹
fs.readdir('../资料', (err, data) =>{
if(err){
console.log('读取失败')
return
}
console.log(data)
})
// 删除文件夹 rm remove 移除
fs.rmdir('./html', err =>{
if(err){
console.log('删除失败')
return
}
console.log('删除成功')
})
// 递归删除:不推荐使用
fs.rmdir('./a', {recursive: true},err =>{
if(err){
console.log('删除失败')
return
}
console.log('删除成功')
})
//建议使用
fs.rm('./a',{recursive: true}, err =>{
if(err){
console.log('删除失败')
return
}
console.log('删除成功')
})
13、查看资源状态
// 引入 fs 模块
const fs = require('fs')
// stat 方法 status 缩写 状态
fs.stat('./座右铭.txt', (err, data) => {
if(err){
console.log(err)
console.log('操作失败')
return
}
console.log(data)
// isFile 检查是否为文件
console.log(data.isFile())
// isDirectory 检查是否为文件夹
console.log(data.isDirectory())
})
14、路径补充说明
// 1、导入 fs 模块
const fs = require('fs')
// 相对路径
fs.writeFileSync('./index.html', 'love')
fs.writeFileSync('index.html', 'love')
fs.writeFileSync('../index.html', 'love')
// 相对路径
fs.writeFileSync('D:/index.html', 'love')
fs.writeFileSync('/index.html', 'love')
15、 相对路径的Bug 与 解决
bug:当你想要创建文件的时候,如果使用相对路径的话,新建文件会被添加到 命令行(cmd)中显示的文件位置;
我们想要的是在当前文件夹下,新建文件;
解决方法 :使用__dirname进行路径的拼接,因为__dirname始终表示 当前脚本所在目录的绝对路径
const fs = require('fs')
// 相对路径参照物: 命令行的工作目录
// fs.writeFileSync('./index.html', 'love')
// 绝对路径 ‘全局变量’ 保存的是:所在文件的所在目录的绝对路径
console.log(__dirname)
fs.writeFileSync(__dirname + '/index.html', 'love')
16、文件批量重命名
1、引入fs模块 require('fs');
2、读取code文件夹 fs.readdirSync(path, err=>{}), 这里的返回值是一个数组,每个元素是文件名称;
3、遍历文件夹,修改文件名称,模版字符串,序号小于10的文件,前面拼接0,否则不改变;或者将文件序号按顺序命名,这个时候是在上面需求的基础上,使用index进行拼接。
const fs = require('fs')
// 读取 code 文件夹
const files = fs.readdirSync('./code', err => {
if (err) {
console.log('读取失败')
return
}
console.log('读取成功')
})
// 遍历数组
files.forEach((item, index) => {
let [, name] = item.split('-')
let newName
// 将文件名排序,并且补0,使用index完成
if (index < 10) {
newName = `0${index + 1}-${name}`
} else {
newName = `${index + 1}-${name}`
}
fs.rename(`code/${item}`, `code/${newName}`, err => {
if (err) {
console.log(err)
console.log('操作失败')
return
}
console.log('操作成功')
})
//将文件名小于10的 添加 0
// if(Number(num) < 10){
// newName = `0${num}-${name}`
// console.log(newName)
// fs.rename(`code/${item}`, `code/${newName}`, err => {
// if(err){
// console.log(err)
// console.log('操作失败')
// return
// }
// console.log('操作成功')
// })
// }
})
17、path模块
重点是resolve模块
// 导入 fs
const fs = require('fs')
const path = require('path')
// 写入文件
fs.writeFileSync(__dirname + '/index.html', 'love')
console.log(__dirname + '/index.html') ///Users/dingmiao/Desktop/找工作/node/code/index.html
// resolve 解决
console.log(path.resolve(__dirname, './index.html')) ///Users/dingmiao/Desktop/找工作/node/code/index.html
console.log(path.resolve(__dirname, 'index.html')) ///Users/dingmiao/Desktop/找工作/node/code/index.html
console.log(path.resolve(__dirname, '/index.html')) // /index.html 这种写法不对,拼接之后的路径是绝对路径
//sep分隔符
console.log(path.sep) //window 中输出结果是\ 在Linux中输出结果是/
// parse方法 __dirname ‘全局变量’
console.log(__filename) //文件的绝对路径 ///Users/dingmiao/Desktop/找工作/node/code/18-path模块.js
let str = "\/Users\/dingmiao\/Desktop\/找工作\/node\/code\/18-path模块.js"
console.log(path.parse(str))
/**
* { root: '/',
dir: '/Users/dingmiao/Desktop/找工作/node/code',
base: '18-path模块.js',
ext: '.js',
name: '18-path模块' }
* */
// basename 输出文件名
console.log(path.basename(str)) //18-path模块.js
// dirname 文件的目录名
console.log(path.dirname(str)) ///Users/dingmiao/Desktop/找工作/node/code
// extname 文件的扩展名
console.log(path.extname(str)) //.js