(一)文件系统
在 Node 中,文件系统是非常重要的,服务端的本质就是将本地的文件发送给远程的客户端。Node 通过 fs 模块和文件系统进行交互,文件系统简单来说就是通过Node来操作系统中的文件
(二)同步和异步
fs模块中所有的操作都可以通过同步和异步来选择
同步:会阻塞程序执行,一行执行完才能执行下一行
异步:不会阻塞异步执行,而是在操作完成时,通过回调函数结果将其返回
(三)文件的写入
同步写入:
// 引入fs模块
const fs = require('fs')
// 写文件之前先要打开!
// fs.openSync(path, flags)
// 第一个参数 path,打开的文件路径,如果没有会新建一个
// 第二个参数 flags,打开文件后的操作类型 w(write)写入 r(read)读
// 返回值:该方法会返回一个文件描述符,我们后续通过这个文件描述符,对文件进行各种操作
var hello = fs.openSync('./hello.js', 'w')
// 写入
// fs.writeSync(fd, string, position, encoding)
// 第一个参数:文件操作符
// 第二个参数:写入的内容
// 第三个参数:从哪开始写,不传就重新写
// 第四个参数:写入的编码,默认utf-8
fs.writeSync(hello, '我是hello', 20)
// 其实到这一步,功能已经实现了,还差最后一步,关闭文件 如果不关闭,这个文件会一直占用内存空间 导致性能较差
// fs.closeSync(fd)
// 参数:要关闭文件的描述符
fs.closeSync(hello)
运行
异步写入:
var fs = require('fs')
// callback 回调参数必传 异步操作的结果都是通过回调函数参数返回的
// 文件标识符在回调函数中
// 在node中,回调函数第一个参数永远是error, 异常优先原则
fs.open('./helloTest.js', 'w', (err, fd) => {
console.log(err, fd) // null 31
// 错误判断
if (err) {
console.log(err)
} else {
// 打开成功 写入文件
fs.write(fd, 'hello~~', (erro) => {
if (erro) {
console.log(erro)
} else {
// 写入成功 关闭文件
fs.close(fd, (error) => {
if (error) {
console.log(err)
} else {
console.log('写入成功!文件已关闭!')
}
})
}
})
}
})
同步:
优点:符合人类思维,一步一步的
缺点:没有异常处理情况,有错误程序就崩溃了,会发生阻塞
异步:
优点:有异常处理,没有阻塞,性能好
缺点:出现回调地狱,回调套回调,代码阅读不方便
不过!以上两种方式都不常用哈哈哈,扎心了,最常用的方式是简单文件写入
(四)简单文件写入
直接上代码:
异步:
var fs = require('fs')
// fs.writeFile(path, string, callback)
fs.writeFile('write.js', '这是简单文件写入', (err) => {
if (err) {
console.log(err)
} else {
console.log('简单文件写入成功!')
}
})
简单文件写入不需要 打开、关闭文件 直接写入即可~ writeFile 的源码帮助我们打开 关闭文件,writeFile 是一个封装好的函数
这个api的参数看下:
options 中 flag 这个参数大有用途,刚才简单文件写入的代码,是覆盖内容,写一次把上次的覆盖,然后从头写,那如果想要接着写,追加怎么操作呢?
var fs = require('fs')
// fs.writeFile(path, string, callback)
fs.writeFile('write.js', '这是简单文件写入', { flag: 'a' }, (err) => {
if (err) {
console.log(err)
} else {
console.log('简单文件写入成功!')
}
})
第三个参数中传入一个对象,flag设置为"a",意为 append,这样就可以实现追加
flag中常用的是这几个参数:
‘a’ ---> append(追加)
‘w’ ---> write (写入)
‘r’ ---> read (读)
(六)流式文件写入
以上的写入,只写一次,就是把文件内容写好,执行一次以上的代码,然后一次性写入文件,这样对性能损耗大,可能发生内存溢出,所以同步、异步、简单文件的写入不适合大文件的写入。流式文件相当于拿一个管子,两者相连,慢慢的一点点写入,不是一次性写入
var fs = require('fs')
// 创建可写流
// fs.createWriteStream(path, options)
// path 文件路径
// options 配置参数,一般不写
var ws = fs.createWriteStream('hello.js') // 水管接上了
// 只要流存在 就可以一直写
ws.write('我是1')
ws.write('我是2')
ws.write('我是3')
ws.write('我是4')
ws.write('我是5')
// 监听流打开了 once 绑定一次性事件,触发一次之后自动失效 只能触发一次
ws.once('open', () => {
console.log('流打开了')
})
// 监听流关闭
ws.once('close', () => {
console.log('流关闭了')
})
// 关闭流
ws.end()
A 水管向B水管传数据,A水管关闭 end() 停止输送
B水管关闭 close() 停止接收,所以应该是停止输送 end()