likes
comments
collection
share

node常用内置模块(fs模块)

作者站长头像
站长
· 阅读数 21

node常用内置模块(fs模块)

划分:node常用内置模块(fs模块)文件操作的三个基本概念:权限位、标识符、操作符

1.基本操作类

2.常用API

一般分为异步操作与同步操作,这里使用异步操作试验(一次性的文件操作,没有使用buffer),Node.js中有错误优先的概念,当操作可能会出现错误时,回调函数的第一个参数常是错误对象

const fs = require('fs');
const path = require('path');

// readFile
fs.readFile(path.resolve('msg.txt'), 'utf-8', (error, data) => {
    if (!error) console.log(data);
});

// writeFile (overwrite),路径不存在时,会创建路径,操作配置对象,可省略
fs.writeFile(path.resolve('msg.txt'), 'Hello Node.js', {
    mode: 0o666,        // 权限
    flag: 'a+',         // 追加
    encoding: 'utf-8'   // 编码
}, (error) => {
    if (!error) console.log('write success');
})

// apendFile
fs.appendFile(path.resolve('msg.txt'), '\nHello Node.js', {}, (err) => {
    if (!err) console.log('append success');
});


// copyFile
fs.copyFile(path.resolve('msg.txt'), path.resolve('msg2.txt'), (err) => {
    if (!err) console.log('copy success');
});

// watchFile
fs.watchFile(path.resolve('msg.txt'), {
    interval: 1000
},(curr, prev) => {
    console.log(curr.mtime);
    console.log(`${curr.size} ${prev.size}`);
})
fs.appendFile(path.resolve('msg.txt'), '\nHello Node.js', {}, (err) => {
    if (!err) console.log('append success22');
    setTimeout(() => {
        fs.unwatchFile(path.resolve('msg.txt'));        // 取消监听
    }, 2000);
});

open and close:

fs.open(path.join(__dirname,'msg.txt'),'r',(error,fd)=>{
    if(!error){
        console.log(fd);
        fs.close(fd,(err)=>{
            if(!err) console.log('close success');
        });
    }
});

// 文件读写:

const fs = require('fs');
const path = require('path');



/**
 * read         将数据从磁盘文件中读取到内存中的buffer
 * fd           定位当前被打开的文件
 * buffer       存储读取到的数据
 * offset       表示在buffer那个位置上写入
 * length       读入buffer的长度
 * position     从磁盘文件中的那个位置开始读取
 */
let buf = Buffer.alloc(10);
fs.open(path.join(__dirname,'msg.txt'),'r',(err,rfd)=>{
    if(err) throw err;                              
    fs.read(rfd,buf,1,4,2,(err,readBytes,buffer)=>{        
        console.log(readBytes);
        console.log(buffer);
        console.log(buffer.toString());
    })
    fs.close(rfd);
})



/**
 * write        将数据从内存中buffer的数据写入到磁盘文件中
 */
let buf2 = Buffer.from('1234567890');
fs.open('b.txt','w',(err,wfd)=>{
    fs.write(wfd,buf2,1,4,0,(err,written,buffer)=>{
        console.log(written);
        console.log(buffer);
        console.log(buffer.toString());
    })
    fs.close(wfd);
})

封装文件copy:

const fs = require('fs');
const path = require('path');

function fileCopy(resFile, newFile, bufLen) {
    let buf = Buffer.alloc(bufLen);
    let readOffset = 0;
    fs.open(resFile, 'r', (err, rfd) => {
        if (err) throw err;
        fs.open(newFile, 'w', (err, wfd) => {
            if (err) throw err;
            function readAnWrite() {
                fs.read(rfd, buf, 0, bufLen, readOffset, (err, readBytes, buffer) => {
                    if (!readBytes) {
                        // readBytes === 0 说明读取完毕
                        fs.close(rfd, () => { });
                        fs.close(wfd, () => { });
                        console.log('copy success');
                        return;
                    }
                    readOffset += readBytes;
                    fs.write(wfd, buf, 0, readBytes, err => {
                        if (err) throw err;
                        readAnWrite();
                    });
                });
            }
            readAnWrite();
        })
    })
}
fileCopy(path.join(__dirname, 'msg.txt'), path.join(__dirname, 'b.txt'), 5);

3.常见操作目录API

api:

const fs = require('fs');
const path = require('path');

// access   判断是否有权限访问文件或目录
fs.access(path.join(__dirname,'b.txt'),err=>console.log(err?err:'success'));

// stat 获取文件信息
fs.stat(path.join(__dirname,'b.txt'),(err,stats)=>{
    if(!err) console.log(stats.isFile());
});

// mkdir    创建目录
fs.mkdir(path.join(__dirname,'test/jiang'),{recursive:true},err=>console.log(err?err:'make success'));


// rmdir    删除目录
fs.rmdir(path.join(__dirname,'test'),{recursive:true},err=>console.log(err?err:'dir remove success'));

// readdir  读取目录    返回文件名、目录数组
fs.readdir(path.join(__dirname,'./'),(err,files)=>{
    if(!err) console.log(files);
});

// unlink   删除文件
fs.unlink(path.join(__dirname,'b.txt'),err=>console.log(err?err:'file remove success'));

目录创建之同步实现:

const fs = require('fs');
const path = require('path');

// access   判断是否有权限访问文件或目录
fs.access(path.join(__dirname,'b.txt'),err=>console.log(err?err:'success'));

// stat 获取文件信息
fs.stat(path.join(__dirname,'b.txt'),(err,stats)=>{
    if(!err) console.log(stats.isFile());
});

// mkdir    创建目录
fs.mkdir(path.join(__dirname,'test/jiang'),{recursive:true},err=>console.log(err?err:'make success'));


// rmdir    删除目录
fs.rmdir(path.join(__dirname,'test'),{recursive:true},err=>console.log(err?err:'dir remove success'));

// readdir  读取目录    返回文件名、目录数组
fs.readdir(path.join(__dirname,'./'),(err,files)=>{
    if(!err) console.log(files);
});

// unlink   删除文件
fs.unlink(path.join(__dirname,'b.txt'),err=>console.log(err?err:'file remove success'));

目录创建之异步实现:

const fs = require('fs');
const path = require('path');
const {promisify} = require('util');

// 回调函数形式
function mkDir(dirPath, cb) {
    let parts = dirPath.split('/');
    let index = 1;
    function next() {
        if (index > parts.length) return cb && cb();
        let current = parts.slice(0,index++).join('/');
        fs.access(current,(err)=>{
            if(err){
                fs.mkdir(current,next); // 创建目录,用回调函数创建下一层目录
            }else{
                next();
            }
        })
    }
    next();
}
mkDir('test/test2/test3', () => {
    console.log('创建成功')
})

// 将access 与 mkdir 处理成async/await 风格
// promise 形式
const access = promisify(fs.access);
const mkdir = promisify(fs.mkdir);

async function myMkDir(dirPath,cb){
    let parts = dirPath.split('/');
    for(let index = 1; index <= parts.length;index++){
        let current = parts.slice(0,index).join('/');
        try{
            await access(current);
        }catch(err){
            await mkdir(current);
        }
    }
    cb && cb();
}
myMkDir('test/test2/test3',()=>{
    console.log('创建成功')
});

目录删除之异步:

function myRemDir(dirPath, cb) {
    fs.stat(dirPath, (err, stats) => {
        if (stats.isDirectory()) {
            // 目录
            fs.readdir(dirPath, (err, files) => {
                let dirs = files.map((item) => path.join(dirPath, item));
                let index = 0;
                function next() {
                    if (index == dirs.length) {
                        return fs.rmdir(dirPath, cb);
                    } else {
                        myRemDir(dirs[index++], next);
                    }
                }

                next();
            })

        } else {
            fs.unlink(dirPath, cb);
        }
    });
}
myRemDir(path.join(__dirname, 'temp'), () => {
    console.log('删除成功');
})