File System
- 文件系统模块
- require('fs')
该模块是核心模块,需要使用require导入后使用
该模块提供了操作文件的一些API
1.文件打开读取关闭操作
fs.open(path[, flags[, mode]], callback)
异步打开一个文件
- path:要打开的文件的路径
- flags:打开文件的方式 读/写 r/w
- mode:设置文件的模式 读/写、执行 4/2/1
- callback:文件打开成功或者失败回调进行处理,包含两个参数
err:文件打开失败的错误保存在err,如果成功err为null
fd:被打开文件的标识,和定时器有点像,可以后续去操作文件
// fs.open('1.txt','r',function(err,fd){
// console.log(err) // null
// console.log(fd) // 23
// })
// 多次打开同一份文件,fd会累加
// fs.open('1.txt','r',function(err,fd){
// console.log(err) // null
// console.log(fd) // 24
// })
// 打开不存在的文件
fs.open('2.txt','r',function(err,fd){
console.log(err)
console.log(fd) // undefined
})
// 打开不存在的文件,一般加判断处理
fs.open('2.txt','r',function(err,fd){
console.log(err)
console.log(fd) // undefined
if(err){
console.log('文件打开失败') // 文件打开失败
}else{
comsole.log('文件打开成功')
}
})
-
结果
同步打开一个文件
const fs = require('fs')
// 异步打开,不会阻止下面的操作,比如console.log('ok)
fs.open('1.txt','r',function(err,fd){
console.log(fd) // 再输出23
})
console.log('ok') // 先打印ok
-
结果
// 同步打开,返回结果就是回调函数里面的参数,fd和err,这种操作比较简单,不需要嵌套
let fd = fs.openSync('1.txt','r');
console.log(fd) // 23
fs.read(fd, buffer, offset, length, position, callback)
从指定的文档标识符fd读取文件数据
- fd:通过open方法成功打开一个文件返回的编号
- buffer:buffer对象
- offset: 新的内容添加到buf对象中的第几位(起始位置)
- length: 添加到buffer中的内容长度
- position: 读取文件的第几位开始读取(起始位置),可以不填
- callback :读取的回调函数,其包含3个参数
err:返回错误时
len:文件读取的长度
newBuf:返回的buffer
// 打开一个文件
const fs = require('fs')
fs.open('1.txt','r',function(err,fd){
if(err) {
console.log('打开文件失败')
}else{
// 读取文件
let buf = Buffer.from('123456789')
console.log(buf) // <Buffer 31 32 33 34 35 36 37 38 39>
fs.read(fd,buf,0,4,null,function(err,len,newBuf){
console.log(buf) // <Buffer 61 62 63 34 35 36 37 38 39>
console.log(err) // null
console.log(len) // 3
console.log(newBuf) // <Buffer 61 62 63 34 35 36 37 38 39>
})
}
})
fs.readSync(fd, buffer, offset, length, position)
fs.read函数的同步版本,返回bytesRea的个数
fs.write(fd, buffer[, offset[, length[, position]]], callback)
通过文件标识fd,向指定的文件写入buffer
- fd:打开的文件
- buffer:要写入的数据
- offset:buffer对象中要写入的数据的起始位置
- length:要写入的buffer数据的长度
- position:fd中起始位置
- callback:回调函数
const fs = require('fs')
// 当要对打开的文件进行操作的时候,打开文件的模式应该是读写方式
fs.open('1.txt','r+',function(err,fd){
if(err) {
console.log('文件打开失败')
}else{
// 写入文件
let buf = Buffer.from('123')
// 从buffer的第0个位置写入3个长度,从1.txt第0个位置
fs.write(fd,buf,0,3,0,function(err,len,buf) {
// 回调里面的参数,第一个是err,第二个是写入文件的字符长度,第三个是写入的buffer
console.log(arguments) // [Arguments] { '0': null, '1': 3, '2': <Buffer 31 32 33> }
// 此时写入1.txt文件中abc 变成123
})
}
})
fs.write(fd, string[, position[, encoding]], callback)
把string写入到文档中通过指定的fd,如果string不是buffer对象的实例则会吧值强制转换成一个字符串
const fs = require('fs')
// 当要对打开的文件进行操作的时候,打开文件的模式应该是读写方式
fs.open('1.txt','r+',function(err,fd){
if(err) {
console.log('文件打开失败')
}else{
// 第二种直接写入字符串的方法
fs.write(fd,'123',4,'utf-8',function(){
// 第一个参数是err,写入长度是3,写入的字符串是’123
console.log(arguments) // [Arguments] { '0': null, '1': 3, '2': '123' }
// 1.txt由原来的abcd变成abcd123
})
}
})
fs.writeSync(fd, buffer[, offset[, length[, position]]])
fs.write()的同步版本
fs.writeSync(fd, string[, position[, encoding]])
fs.write()的同步版本
fs.close(fd, callback)
关闭一个打开的文件
// 关闭打开的文件
fs.close(fd,function(err){
console.log(arguments) // [Arguments] { '0': null }
})
fs.closeSync(fd)
fs.close()的同步版本
2.文件写入并创建追加数据
fs.writeFile(file, data[, options], callback)
异步的数据写入一个文件,如果文件不存在则新建,如果文件原先存在,则会被替换。data可以是一个string,也可以是一个原生buffer
- file: 写入的文件
- data:写入该文件的数据
- options: <Object> | <string>
encoding <string> | <null> 默认值: 'utf8'。
mode <integer> 默认值: 0o666。
flag <string> 参阅支持的文件系统标志。默认值: 'w'。
- callback: 回调,参数err
const fs = require('fs')
let file= '2.txt'
fs.writeFile(file,'hello',function(err){
if(err){
console.log('文件打开失败')
}else{
//结果会在当前目录下创建一个2.txt并且值为hello
}
})
fs.writeFileSync(file, data[, options])
fs.writeFile的同步版本。注意:没有callback,也不需要
fs.appendFile(path, data[, options], callback)
异步的将数据添加到一个文件的尾部,如果文件不存在,会创建一个新的文件。data可以是一个string,也可以是原生buffer
const fs = require('fs')
let file= '2.txt'
fs.appendFile(file,'violet',function(err){
console.log(arguments) // [Arguments] { '0': null }
// 此时2.txt 值由原来的hello 变成helloviolet
})
fs.appendFileSync(path, data[, options])
fs.appendFile的同步版本
fs.access(path[, mode], callback)
测试用户对 path 指定的文件或目录的权限
- 使用场景:
不建议在调用 fs.open()、 fs.readFile() 或 fs.writeFile() 之前使用 fs.access() 检查文件的可访问性。应该直接打开、读取或写入文件,如果文件无法访问则处理引发的错误
- mode: 参数是一个可选的整数,指定要执行的可访问性检查。
- callback :参数err
fs.stat(path[, options], callback)
不建议在调用 fs.open()、 fs.readFile() 或 fs.writeFile() 之前使用 fs.stat() 检查文件是否存在。 而是应该直接打开、读取或写入文件,如果文件不可用则处理引发的错误。
- 要检查文件是否存在但随后并不对其进行操作,则建议使用 fs.access()。
例子:
实现文件不存在则创建文件并写入值,文件存在则追加内容到该文件
- 异步实现
const fs = require('fs')
let fileName = '3.txt'
fs.stat(fileName, (err,stats) => {
console.log(err,stats)
if(err && err.code ==='ENOENT') {
// 文件不存在
fs.writeFile(fileName,'violet',function(err,fd){
if(err) {
console.log('文件创建失败')
}else{
console.log('文件创建成功')
}
// 第一次执行线上 文件创建成功,并且3.txt创建成功,且值为violet
})
}else{
fs.appendFile(fileName,'疏影流苏',function(err){
if(err) {
console.log('文件追加失败')
}else{
// 第二次执行线上 文件创建成功,并且3.txt创建成功,且值由violet变为violet疏影流苏
console.log('文件追加成功')
}
})
}
});
- 同步实现
let fileName = '3.txt'
if (!fs.existsSync(fileName)) {
console.log('文件创建成功');
// 第一次执行线上 文件创建成功,并且3.txt创建成功,且值为violet
fs.writeFileSync(fileName,'vlolet')
}else{
console.log('文件追加成功')
// 第二次执行线上 文件创建成功,并且3.txt创建成功,且值由violet变为violet疏影流苏
fs.appendFileSync(fileName,'疏影流苏')
}
fs.existsSync(path)
如果路径存在,则返回 true,否则返回 false。
fs.readFile(path[, options], callback)
- path:文件名或文件描述符。
- options:encoding编码方式
- callback:参数err以及data,其中 data 是文件的内容
const fs = require('fs')
fs.readFile('3.txt',function(err,data){
// data 是buffer对象
if(err){
console.log('文件读取失败')
}else{
// 将buffer对象转成字符串
console.log(data.toString()) // vlolet疏影流苏
}
})
fs.readFileSync(path[, options])
fs.readFile的同步版本
const fs = require('fs')
let buf = fs.readFileSync('3.txt')
console.log(buf.toString()) // // vlolet疏影流苏
3.文件重命名及删除
fs.unlink(path, callback)
异步地删除文件或符号链接。 除了可能的异常,完成回调没有其他参数。
const fs = require('fs')
fs.unlink('2.txt',function(err){
if(err) {
console.log('删除失败')
}else{
console.log('删除成功')
// 结果就是将2.txt在目录下删除
}
})
fs.unlinkSync(path)
fs.unlink的同步方法
fs.rename(oldPath, newPath, callback)
对文件重命名
const fs = require('fs')
fs.rename('3.txt','3.new.txt',function(err){
console.log(arguments) // [Arguments] { '0': null }
// 执行结果 3.txt变成3.new.txt
})
fs.renameSync(oldPath, newPath)
fs.rename的同步版本
fs.stat(path[, options], callback)
读取文件状态信息
const fs = require('fs')
fs.stat('3.new.txt',function(){
console.log(arguments)
})
- 结果
fs.statSync(path[, options])
fs.stat的同步版本
fs.watch(filename[, options][, listener])
观察指定路径的改变,filename路径可以是文件或者目录
// 有的系统不支持,不稳定
const fs = require('fs')
let filename = '3.new.txt'
// 第一个监听的文件
//第二个设置,不填
// 第三个是回调
fs.watch(filename,(eventType,fn) => {
console.log(`事件类型是: ${eventType}`)
if(fn){
console.log(`${fn}发生了变化`)
}else{
console.log('没发生变化')
}
})
4.操作文件夹
fs.mkdir(path[, options], callback)
创建文件夹
const fs = require('fs')
fs.mkdir('./4',function(){
console.log(arguments) // [Arguments] { '0': null }
// 会在当前file文件夹下创建一个4的文件夹
})
fs.mkdirSync(path[, options])
fs.mkdir的同步版本
fs.readdir(path[, options], callback)
读取文件夹
fs.readdir('./',(err,fileList)=> {
console.log(fileList)
})
-
结果
fs.readdirSync(path[, options])
// 读取文件夹,判断是文件夹还是文件
fs.readdir('../File',(err,fileList)=> {
console.log(fileList)
fileList.forEach((f)=> {
fs.stat(f,(err,stat)=> {
// mode 可以判断是文件夹还是文件
switch(stat.mode) {
case 16877:
console.log(`[文件夹]${f}`)
break;
case 33188:
console.log(`[文件]${f}`)
break;
}
})
})
})
- 结果
fs.readdir的同步版本
fs.rmdir(path[, options], callback)
删除文件夹
// 执行完成就会删除文件夹
fs.rmdir('./5',()=> {
console.log(arguments)
})
fs.rmdirSync(path[, options])
fs.rmdir的同步版