官方文档:
http://nodejs.cn/api/fs.html#fs_fifile_system_flflags
1.文件的常用api操作
引入文件系统模块fs
fs.readFile(path[, options], callback)
读取文件
path:文
件路径
callback:
回调函数
err
data
:
读取的数据
const fs = require('fs');
fs.readFile('./hello.txt',(err,data) => {
if(err) throw err;
console.log(data);
console.log(data.toString());
})
fs.readFile('./hello.txt','utf8',(err,data) => {
if(err) throw err;
console.log(data);
})
结果:
<Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64 20 21 21> //不指定编码,直接输出是buffer,需要转换为字符串输出
hello world !!
hello world !! //指定编码格式则不用转换
fs.writeFile(fifile, data[, options], callback)
写文件
file:文
件名或文件描述符。
data
:
写入的数据
options :
encoding
:
写入字符串的编码格式
默认值
:
'utf8'
。
mode:文
件模式
(
权限
)
默认值
:
0o666
。
flag:
默认值
:
'w'
。
callback
回调函数
err
fs.writeFile('./hello.txt','this is a test','base64',err => {
if(err) throw err;
console.log('写入成功');
})
fs.writeFile('./hello.txt','this is a test',err => {
if(err) throw err;
console.log('写入成功');
})
结果:
写入成功
写入成功
fs.appendFile(path, data[, options], callback) 追加数据到文件
path :文
件名或文件描述符。
data:
追加的数据
options:
encoding:
写入字符串的编码格式
默认值
:
'utf8'
。
mode:文
件模式
(
权限
)
默认值
:
0o666
。
flag:
默认值
:
'a'
。
callback
回调函数
err
const buf = Buffer.from('hello world!')
fs.appendFile('./hello.txt',buf,(err) => {
if(err) throw err;
console.log('追加成功');
})
fs.stat(path[, options], callback)
获取文件信息,判断文件状态(是文件还是文件夹)
path
options
bigint:
返回的
fs.Stats
对象中的数值是否应为
bigint
型。
默认值
:
false
。
callback
err
stats
:文件信息
fs.stat('./hello.txt',(err,stats) => {
if(err){
console.log('文件不存在');
return;
}
console.log(stats);
console.log(stats.isFile());
console.log(stats.isDirectory());
})
结果:
Stats {
dev: 990155,
mode: 33206,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: 4096,
ino: 281474976727371,
size: 26,
blocks: 0,
atimeMs: 1580183562585.1301,
mtimeMs: 1580184715489.0725,
ctimeMs: 1580184715489.0725,
birthtimeMs: 1580183562585.1301,
atime: 2020-01-28T03:52:42.585Z,
mtime: 2020-01-28T04:11:55.489Z,
ctime: 2020-01-28T04:11:55.489Z,
birthtime: 2020-01-28T03:52:42.585Z
}
true
false
fs.rename(oldPath, newPath, callback)
重命名文件
oldPath:
旧文件路径名字
newPath:
新文件路径名字
callback
回调函数
err
fs.rename('./hello.txt','./test.txt',err => {
if(err) throw err;
console.log('重命名成功');
})
结果:
重命名成功
fs.unlink(path, callback)
删除文件
path
| |
callback
err
fs.unlink('./test.txt',err => {
if(err) throw err;
console.log('删除成功');
})
结果:删除成功
2.使用文件系统操作文件夹
fs.mkdir(path[, options], callback)
创建文件夹
path
| |
options
|
recursive
是否递归创建
默认值
:
false
。
mode
⽂件模式(权限)
Windows
上不⽀持。
默认值
:
0o777
。
callback
err
const fs =require('fs');
fs.mkdir('./a',err => {
if(err) throw err;
console.log('创建文件夹成功');
})
fs.mkdir('./b/c',{
recursive:true
},err => {
if(err) throw err;
console.log('创建文件夹成功');
})
结果:
fs.readdir (path[, options], callback)
读取文件夹
path
| |
options
|
encoding
默认值
:
'utf8'
。
withFileTypes
默认值
:
false
。
callback
err
files
fs.readdir('./',(err,files) => {
if(err) throw err;
console.log(files)
})
fs.readdir('./',{
withFileTypes:true
},(err,files) => {
if(err) throw err;
console.log(files)
})
fs.readdir('./',{
encoding:'buffer', //设置buffer,files返回文件名为buffer对象
withFileTypes:true //单个文件类型
},(err,files) => {
if(err) throw err;
console.log(files)
})
结果:
[ 'a', 'b', 'file_test.js' ]
[
Dirent { name: 'a', [Symbol(type)]: 2 },
Dirent { name: 'b', [Symbol(type)]: 2 },
Dirent { name: 'file_test.js', [Symbol(type)]: 1 }
]
[
Dirent { name: <Buffer 61>, [Symbol(type)]: 2 },
Dirent { name: <Buffer 62>, [Symbol(type)]: 2 },
Dirent {
name: <Buffer 66 69 6c 65 5f 74 65 73 74 2e 6a 73>,
[Symbol(type)]: 1
}
]
2:文件夹, 1 :文件
fs.rmdir(path[, options], callback)
删除文件夹
path
| |
options
maxRetries
重试次数。出现这类错误
EBUSY
、
EMFILE
、
ENFILE
、
ENOTEMPTY
或 者EPERM
,每⼀个重试会根据设置的重试间隔重试操作。如果
recursive
不为
true
则 忽略.
默认值
:
0
。
retryDelay
重试的间隔,如果
recursive
不为
true
则忽略
.
默认值
:
100
。
recursive
如果为
true
,则执行递归的目录删除。在递归模式中,如果
path
不存 在则不报告错误,并且在失败时重试操作。默认值
:
false
。
callback
err
fs.rmdir('./b',err => {
if(err) throw err;
console.log('删除文件夹成功');
})
fs.rmdir('./b',{
recursive:true
},err => {
if(err) throw err;
console.log('删除文件夹成功');
})
错误代码意义:https://blog.csdn.net/a8039974/article/details/25830705
监听文件变化
chokidar
初始化: npm init -y
安装chokidar:npm install chokidar --save-dev
Chokidar.watch(path,[options])
fs.watch('./',(eventType,filename) => {
console.log(eventType,filename)
})
fs.watch('./',{
recursive:true //监听文件夹下的子目录
},(eventType,filename) => {
console.log(eventType,filename)
})
结果:
在启动程序过程中新建一个文件,进行修改,就会运行程序
初始化,安装,推荐使用这一个,因为上面那一个,操作一下,会显示两行
const fs =require('fs');
const chokidar =require('chokidar');
chokidar.watch('./',{
ignored:'./node_modules'
}).on('all',(event,path) => {
console.log(event,path)
})
3.创建读取文件流和创建写入文件流
Node.js
中有四种基本的流类型:
Writable
-
可写入数据的流(例如
fs.createWriteStream()
)。
Readable
-
可读取数据的流(例如
fs.createReadStream()
)。
Duplex
-
可读入可写的流(例如
net.Socket
)。
Transform
-
在读写过程中可以修改或转换数据的
Duplex
流(例如
zlib.createDeflate()
)。
创建读取文件流
fs.createReadStream(path[, options])
const fs = require('fs');
let rs = fs.createReadStream('./streamTest.js',{
highWaterMark:100
});
let count = 1;
rs.on('data',chunk => {
console.log(chunk.toString())
console.log(count++)
})
rs.on('end',()=>{
console.log('读取完成')
});
结果:
F:\node\node_js\4 file>node streamTest.js
const fs = require('fs');
let rs = fs.createReadStream('./streamTest.js',{
highWaterMark:100
});
1
let count = 1;
rs.on('data',chunk => {
console.log(chunk.toString())
console.log(count++)
})
r
2
s.on('end',()=>{
console.log('读取完成')
});
3
读取完成
创建写入文件流
fs.createWriteStream(path[, options])
let ws = fs.createWriteStream('./a.txt');
let num = 1;
let timer = setInterval(() => {
if(num < 10){
ws.write(num + '')
num++
}else{
ws.end("写入完成");
clearInterval(timer)
}
}, 200);
ws.on('finish',()=>{
console.log('写入完成')
})
结果:
管道流:从数据流来源中一段一段通过管道流向目标。
readable.pipe(destination[, options])
let rs = fs.createReadStream('./streamTest.js');
let ws = fs.createWriteStream('./a.txt');
rs.pipe(ws)
结果:
4. path模块常用的一些api
path.basename(path[,ext]) 返回path的最后一部分
path.dirname(path) 返回path的目录名
path.extname(path) 返回path的扩展名
path.join([...paths]) 路径拼接
path.normalize(path) 规范化路径
path.resolve([...paths]) 将路径解析为绝对路径
path.format(pathObject) 从对象中返回路径字符串
path.parse(path) 返回一个对象,包含path的属性
path.sep 返回系统特定的路径片段分隔符
path.win32 可以实现访问windows的path方法
__fifilename 表示当前正在执行的脚本的文件名
__dirname 表示当前执行脚本所在的目录
const path = require('path');
console.log("basename"+path.basename('/nodejs/2-6/index.js','.js'))
ES6 语法:
const {basename,dirname,extname,join,normalize,resolve,format,parse,sep,win32} = require('path');
console.log("ES6 : "+basename('/nodejs/file/index.js','.js'))
console.log("dirname: "+dirname('/nodejs/file/index.js'))
console.log("extname: "+extname('index.'))
console.log("join: "+join('/nodejs/','/index.js'))
console.log("normalize: "+normalize('/nodejs/test/../index.js'))
console.log("resolve "+resolve('./pathTest.js'))
let pathObj = parse('/nodejs/test/index.js');
console.log("parse: "+pathObj)
console.log("format: "+format(pathObj))
console.log("当前系统下分隔符 " + sep)
console.log("windows下分隔符 " + win32.sep)
console.log("filename " + __filename) //这个绝对路径一定是正确的
console.log("__dirname"+__dirname)
console.log("resolve " + resolve('./pathTest.js')) //执行启动命令的绝对路径,有时会不正确
结果:
basenameindex
ES6 : index
dirname: /nodejs/file
extname: .
join: \nodejs\index.js
normalize: \nodejs\index.js
resolve F:\node\node_js\4 file\pathTest.js
parse:
{
root: '/',
dir: '/nodejs/test',
base: 'index.js',
ext: '.js',
name: 'index'
}
format: /nodejs/test\index.js
当前系统下分隔符 \
windows下分隔符 \
filename F:\node\node_js\4 file\pathTest.js
__dirnameF:\node\node_js\4 file
resolve F:\node\node_js\4 file\pathTest.js