path模块用于对路径和文件进行处理,提供了很多好用的方法。
并且我们知道在Mac OS、Linux和window上的路径时不一样的
可移植操作系统接口
path常见的API
从路径中获取信息
路径的拼接
将文件和某个文件夹拼接
const path = require('path')
const filePath = 'stu_node/learn_node/03_path/test.txt'
// 1.获取路径信息
console.log(path.dirname(filePath)) //stu_node/learn_node/03_path
console.log(path.basename(filePath)) //test.txt
console.log(path.extname(filePath)) //.txt
// 2.join路径拼接
const basePath = 'stu_node/learn_node/03_path'
const fileName = 'test.txt'
console.log(path.join(basePath, fileName)) //stu_node\learn_node\03_path\test.txt
// 3.resolve拼接,会判断路径中是否有./ ../
console.log(path.resolve(basePath, fileName)) //C:\Users\yihua\Desktop\code\stu_node\learn_node\03_path\stu_node\learn_node\03_path\test.txt
借助于Node帮我们封装的文件系统,我们可以在任何的操作系统(window、Mac OS、Linux)上面直接去操作文件
const fs = require('fs')
// 读取文件信息
const filePath = './abc.txt'
// 1.同步操作
const info = fs.statSync(filePath)
// 后续的代码会被阻塞
console.log(info)
// 2.异步操作,不阻塞
fs.stat(filePath,(err,info)=>{
if(err){
console.log(err);
}else{
console.log(info);
}
})
// 3.promise,不阻塞
fs.promises.stat(filePath).then(info=>{
console.log(info);
}).catch(err=>{
console.log(err);
})
是什么?
为了简化用户的工作,Node.js 抽象出操作系统之间的特定差异,并为所有打开的文件分配一个数字型的文件描述符
fs.open() 方法用于分配新的文件描述符
const fs = require('fs')
fs.open('./abc.txt',(err,fd)=>{
if(err){
console.log(err);
}else{
console.log(fd);
// 通过文件描述符去操作文件
fs.fstat(fd,(err,info)=>{
console.log(info);
})
}
})
flag选项
const fs = require('fs');
// 1.文件写入
const content = "hello node";
fs.writeFile('./abc.txt', content, {flag: "a"}, err => {
console.log(err);
});
// 2.文件读取
fs.readFile("./abc.txt", {encoding: 'utf-8'}, (err, data) => {
console.log(data);
});
encoding选项:https://www.jianshu.com/p/899e749be47c
const fs = require('fs')
const path = require('path')
// 1.创建文件夹
const dirname = './yihua'
// if (!fs.existsSync(dirname)) {
// fs.mkdir(dirname, err => {
// console.log(err)
// })
// }
// 2.读取文件夹中的所有文件
fs.readdir(dirname, (err, files) => {
console.log(files)
})
function getFiles (dirname) {
fs.readdir(dirname, { withFileTypes: true }, (err, files) => {
for (let file of files) {
// fs.stat(file) 可以, 但是有点麻烦
if (file.isDirectory()) {
const filepath = path.resolve(dirname, file.name)
getFiles(filepath)
} else {
console.log(file.name)
}
}
})
}
getFiles(dirname)
// 3.重命名
fs.rename('./yihua', './test', err => {
console.log(err)
})
const fs = require('fs')
const path = require('path')
const sourceDir = 'source'
const targetDir = './target'
const walkSync = (curDirPath, cb) => {
fs.readdirSync(curDirPath, {withFileTypes: true}).forEach(dir => {
const filePath = path.join(curDirPath, dir.name)
if (dir.isFile()) {
cb(filePath)
}else if (dir.isDirectory()) {
const dirname = path.join(curDirPath.replace(sourceDir, targetDir),dir.name)
// 创建文件夹
if (!fs.existsSync(dirname)) {
fs.mkdir(dirname,err=>{
console.log(err);
})
}
walkSync(filePath, cb)
}
})
}
const copyFile = filePath => {
console.log(filePath, filePath.replace(sourceDir, targetDir))
fs.copyFile(filePath, filePath.replace(sourceDir, targetDir), (err) => {
console.log(err)
})
}
walkSync(sourceDir, copyFile)
发出事件和监听事件都是通过EventEmitter类来完成的,它们都属于events对象。
const EventEmitter = require('events')
// 1.创建发射器
const emitter = new EventEmitter()
// 2.监听事件
emitter.on('click', (...args) => {
console.log('监听1', args)
})
const listener2 = (...args) => {
console.log('监听2到click事件', args)
}
emitter.on('click', listener2)
// 3.触发事件
setTimeout(() => {
emitter.emit('click', 'yihua', 18, '男')
emitter.off('click', listener2)
emitter.emit('click', 'yihua', 18, '男')
}, 2000)
console.log(emitter.eventNames())
console.log(emitter.getMaxListeners())
console.log(emitter.listenerCount('click'))
console.log(emitter.listeners('click'))
// 只执行一次
emitter.once('click', (...args) => {
console.log('监听1到click事件', args)
})
// 将本次监听放到最前面
emitter.prependListener('click', (...args) => {
console.log('监听2到click事件', args)
})
emitter.prependOnceListener('click', (...args) => {
console.log('监听2到click事件', args)
})
emitter.removeAllListeners('click')