写在最前:跟着视频学习只是为了在新手期快速入门。想要学习全面、进阶的知识,需要格外注重实战和
官方技术文档
,文档建议作为手册使用
fs模块提供了对文件、文件夹操作的能力。在这个模块中,写入的数据如果想要换行,需要使用\r\n
,而不是\n
另外请注意,读取到的都是Buffer
,你需要按照文件的格式选择对应的方法将其转化为需要的数据,比如读取txt文件,你可以使用toString()
进行转换
引入fs模块
const fs = require('fs')
需要持久化保持数据时,除了直接存储在数据库,还有可以利用文件写入
语法:fs.writeFile(file, data[, options], callback)
示例:
const fs = require('fs')
fs.writeFile('./hello.js', 'console.log('hello node')', (res) => {
console.log(res)
// 写入失败则res 为 Error对象, 成功则为null
})
语法:fs.writeFileSync(file, data[, options])
, 注意没有回调函数
fs.writeFile('./hello.js', 'console.log('hello nodeSync')')
追加写入时在指定文件末尾添加内容
语法: fs.appendFile(file, data[, options], callback)
、fs.appendFileSync(file, data[, options])
二者返回undefined
优势:可以减少打开关闭文件的次数,适合大文件写入或者频繁写入,流式写入可以在这种场景下提高性能
语法: fs.createWriteStream(path[, options])
返回值:Object
使用流式写入时,需要先和文件建立通道: const ws = createWriteStream('filePath')
然后可以使用ws.wirte(data)
写入内容,文件内容写入完毕后,使用ws.close()
关闭通道,通道关闭前都可以向对应文件中写入数据
const ws = fs.createWriteStream('filePath')
// 流式写入数据
ws.write('hello world\r\n')
// 关闭通道
ws.close()
当需要读外部文件获取信息时候都要进行文件读取,比如读音乐、读视频、读系统文件等等
语法:fs.readFile(path[, options], callback(err, data))
返回值:undefined
读取到的data是一个Buffer
,需要进行处理
const fs = require('fs')
fs.readFile('./hello.js', (err, data) => {
if(err){
// ...
}
// 读取到的是Buffer, 还需要转字符串
if(data){
data = data.toString()
}
})
语法: fs.readFileSync(path[, options])
返回值: Buffer
,读取结果
const fs = require('fs')
let data = fs.readFileSync('./hello.js')
const fileInfo = data.toString()
同样的你需要建立一个通道, 创建读取流对象: const rs = fs.createReadStream(path[, options], callback)
rs.on('data', (chunk) => {})
,绑定data
事件, chunk
是流式读取时每次读取到的Buffer
块,通过length
属性可以获取每个块的字节大小rs.on('end', () => {})
,绑定end
事件非流式就是读完了然后写进一个新的,操作都简单就不用说了,这里主要记流式,边读边写。流式也是经常使用的方式,因为更适合读大文件的情景。并且对资源的利用更优
const rs = fs.createReadStream('./hello.js')
const ws = fs.createWriteStream('./hello_copy.js')
rs.on('data', chunk => {
ws.write(chunk)
})
rs.on('end', () => {
alert('文件复制完毕')
})
管道快速复制文件(不大的):
rs.pipe(ws)
要用到fs
模块提供的rename()
API
语法:fs.rename(path, newPath, callback(err))
同步版本: fs.renameSync(path, newPath)
const fs = require('fs')
fs.rename('./hello.js', './newName.js', err => {
if(err){
//...
}else{
//...
}
})
通过上面的例子可以看到,这个API也可以用于移动文件
要用到fs
模块提供的unlink
或unlinkSync
语法:unlink( path, callback(err) )
同步版类推
代码示例省略
node 14.4版本引入了新的删除文件API —— rm
、rmSync
语法:fs.rm( path. callback(err) )
API | 功能 |
---|---|
mkdir、mkdirSync | 创建文件夹 |
readdir、readdirSync | 读取文件夹 |
rmdir、rmdirSync (这两个api将来会被移除)、rm(建议使用) | 删除文件夹 |
1、创建文件夹
和linux命令名一样是mkdir
语法: fs.mkdir( path[, options], callback(err) )
const fs = requrie('fs')
fs.mkdir('./newFile.txt', err => {
// ...
})
// 递归创建
fs.mkdir('./a/b/c', { recursive: true }, err => {
// ...
}
2、文件夹读取
语法:fs.readdir( path, callback( err, data ) )
fs.readdier('./hello.js', (err, data) => {
if(err){
//...
}
// 处理读取结果data
})
3、删除文件夹
语法:fs.rm( path, callback(err) )
递归删除: fs.rm( path, { } )
fs.rm('./a', { recursive: true }, err => {
//...
})
语法: fs.state( path, [, options], callback(err, data) )
、同步版本fs.stateSync
data结构:
会用到的全局变量:
__dirname
:可以获取其所在文件的所在目录的绝对路径,这可以避免工作目录变化的影响。__filename
:当前文件的绝对路径
常用API:
API | 功能 |
---|---|
path.resolve | 拼接规范的绝对路径 |
path.sep | 获取操作系统的路径分隔符 |
path.parse( filePath ) | 解析路径并返回对象 |
path.basename( filePath ) | 获取路径的基础名称 |
path.dirname( filePath ) | 获取路径的目录名 |
path.extname( filePath ) | 获取路径的扩展名 |
语法: path.resolve( 绝对路径, 相对路径 )
const path = require('path')
let filePath = path.resolve(__dirname, './hello.js')
let filePath = path.resolve(__dirname, 'hello.js') // 不写./也可以
语法: path.sep
区别: window下返回值是\
,Linux下结果是/
语法: path.parse( filePath )
返回值是一个Object:
Http报文相关在AJAX基础已经学了这里省略
去看计网
从这里开始,就是后端基础了,node后端需要借助这个http模块进行
const http = require('http')
语法: http.createServer( (request, response) => {} )
参数:
const server = http.createServer( (res, req) => {
// ...
response.end('响应结束')
} )
响应内容中文乱码的解决
在请求头中规定文本类型
const server = http.createServer( (res, req) => {
// 设置接受的文本类型
response.setHeader('Content-Type', 'text/html; charset=utf-8')
response.end('响应结束')
} )
语法: server.listen( port, callback )
参数:
http协议默认端口是80, https协议的默认端口是443,http服务开发常用端口有3000、8080、8090、9000等
解义 | 获取语法 |
---|---|
method - 请求方法 | request.method |
httpVersion - http协议版本号 | request.httpVersion |
url - 请求路径 | request.url |
url路径 | request(‘url’).parse(request.url).pathname |
url查询字符串, 以此可以获取query参数 | request(‘url’).parse(request.url, true).query |
header - 请求头 | request.headers |
data - 请求体 | request.on(‘data’, (chunk) => {})、request.on(‘end’, ()=>{}) |
获取请求体的流程
const url = require('url')
const server = http.createServer( (req, res) => {
// 获取请求方法
let { method } = req
// 解析url
let resUrl = new URL(req.url , ip)
let pathName = resUrl.pathname
let query = res.query
let body = ''
// ...
request.on('data', (chunk) => {
body += chunk
})
request.on('end', () => {
console.log(body)
// 响应
response.end(body)
})
} )
作用 | 语法 |
---|---|
code - 设置响应状态码 | response.statusCode |
message - 设置响应状态描述 | response.statusMessage |
header - 响应头信息 | response.setHeader(‘头名’, ‘头值’) |
data - 响应体,即后端返回给前端的前台需要的数据 | response.write(data) response.end(‘end’) |
对接过后端的应该可以很清晰看出来都是些什么作用,所以就直接写示例了
const server = http.createServer( (req, res) => {
// ... 根据一些情况进行处理并设置状态码、message、header等信息
if(xxxxx){
response.statusCode == xxxx
response.statusMessage = 'xxxxx'
response.setHeader('Content-Type': ['yyyy', 'qqqq'])
}
// ...
// 设置响应体
response.write(yourData)
// ...
request.on('data', (chunk) => {
body += chunk
})
// ....
response.end()
} )
媒体类型mime
是一种标准,用来表示文档、文件或者字节流的性质和格式
HTTP服务可以设置响应头Conent-Type
来表示响应体的MIME类型,浏览器会根据该类型决定如何处理资源
常见文件的mime类型
文件类型 | 对应mime类型 |
---|---|
html | text/html |
css | text/css |
js | text/javascript |
png | image/png |
jpg | image/jpeg |
gif | image/gif |
mp4 | vidio/mp4 |
mp3 | audio/mpeg |
json | application/json |
对于未知的资源类型,可以使用application/octet-stream
类型,浏览器在遇到该类型的响应时,会对响应体内容进行独立存储
headers里面设置字符集编码utf-8
对err.code进行switch case
GET请求使用场景: