zoukankan      html  css  js  c++  java
  • Nodejs文件相关操作

    欢迎关注我的博客我在马路边

    适用人群

    本文适用于刚接触Node的小白,毕竟我也是小白,大佬请绕行。

    Node文件操作

    在实际开发中遇到很多有关文件及文件夹的操作,比如创建、删除文件及文件夹,文件拷贝、压缩和生产word等。用到文件系统、流操作以及相关依赖等,封装了一些常用的方法可供重复使用。

    常用API

    具体API参考:Node.js中文网(点击前往),API对各种方法的使用介绍已经很详细,下面不过多介绍,主要写一些开发中遇到的问题以及重构方法。
    在操作过程中一般会遇到同步和异步操作,一般方法以Sync结尾均为同步操作,异步一般通过回调函数或者监听来实现同步效果。

    fs文件系统

    文件操作是很常见的方式,下面简述同步和异步操作的方法,文件流操作需要通过管道通信来监听,具体事件可参考:监听事件

    // 引用文件系统
    const fs = require('fs');
    // 文件操作最长遇到的问题:同步、异步操作
    // 文件读取异步操作
    fs.readFile('/etc/passwd', (err, data) => {     // 回调函数
        if (err) throw err;
        console.log(data);
    });
    // 文件读取同步操作
    fs.readFileSync('<directory>');
    // 文件流操作
    fs.createReadStream('sample.txt', { encoding: 'utf-8'});
    fs.createWriteStream('sample.txt'), { close: false }).on('close', function(){
        // 监听close事件实现文件流传输同步操作
        ...
    })
    // 通过文件流将文件从A拷贝到B
    fs.createReadStream('/A/sample.txt', { encoding: 'utf-8'}).pipe(fs.createWriteStream('/B/sample.txt'), { close: false }).on('close', function () {
       // 监听close事件实现文件流传输同步操作
       ...
    });
    
    

    officegen Office插件

    导出word依赖officegen包,git地址。详细介绍了各种API的使用方式,当然这里也是异步的。

    // 引入officegen
    const officegen = require('officegen');
    
    // 创建 ppt 2007 :
    var pptx = officegen ( 'pptx' );
    // 创建 Word 2007 :
    var docx = officegen ( 'docx' );
    // 创建 Excel 2007 :
    var xlsx = officegen ( 'xlsx' );
    // 以创建ppt为例
    pptx.setDocTitle ( '<title>' );
    var out = fs.createWriteStream ( 'out.pptx' );      // 流输出创建文件
    pptx.generate ( out );
    out.on ( 'close', function () {
      console.log ( 'Finished to create the PPTX file!' );      // 回调执行接下步骤达到同步操作
    });
    

    封装重用方法

    封装了删除、创建文件夹及文件的方法,以及重复生成word文件方法。

    文件操作

    采用递归创建不重复名称的文件夹,filePath为文件夹路径,num为初始状态0

    
    /**
     * 创建文件夹
     * @param {*} filePath 
     * @param {*} num 
     */
    function mkDifDir(filePath, num) {
        var newFilePath = filePath;
        while (fs.existsSync(newFilePath) && fs.statSync(newFilePath).isDirectory()) {
            num++;
            newFilePath = filePath + '(' + num + ')'
        }
        fs.mkdirSync(newFilePath);
        return newFilePath;
    }
    
    // 调用方式
    mkDifDir('D://abc', 0);
    // 返回结果
    // 如果目标目录存在abc文件夹,则创建abc(1)文件夹,返回D://abc(1),否则直接创建abc文件夹
    // 如果还存在abc(1)文件夹,则依次类推直到不重复创建出abc(n)文件夹位置并返回值
    

    根据传入多及目录递归创建文件夹

    /**
     * 创建多层目录文件
     * @param {*} dirname 
     */
    function mkdirsSync(dirname) {
        if (fs.existsSync(dirname)) {
            return true;
        } else {
            if (mkdirsSync(path.dirname(dirname))) {
                fs.mkdirSync(dirname);
                return true;
            }
        }
    }
    // 调用方式
    mkdirsSync('D://a//b//c//d//e//f');
    // 返回结果
    // 会在D盘下依次生成a==>b==>c==>d==>e==>f文件结构的文件夹
    // 如果存在D://a//b//c//d则会在d下创建e==>f文件结构的文件夹
    

    上述方法的进阶版,也是调用上述方法,再嵌套一层,可以直接一句目录创建出文件夹及文件

    /**
     * 创建文件包含文件夹目录
     * @param {*} filePath 
     */
    function createFile(filePath) {
        var dirPath = path.dirname(filePath);
        mkdirsSync(dirPath);
        if (!fs.existsSync(filePath)) {
            fs.writeFileSync(filePath, '', { // 创建文件
                encoding: 'utf-8'
            })
        }
    }
    // 调用方式
    mkdirsSync('D://a//b//c//d//e//f//abc.txt');
    // 返回结果
    // 会在D盘下依次生成a==>b==>c==>d==>e==>f文件结构的文件夹,并在f文件夹下创建acb.txt
    // 如果存在D://a//b//c//d则会在d下创建e==>f文件结构的文件夹,并在f文件夹下创建acb.txt
    

    根据目录删除文件夹下的所有文件及文件夹下的内容,同样也是递归操作

    /**
     * 删除url下所有的内容
     * @param {*} url 
     */
    function deleteAllFiles(url) {
        var files = [];
        files = fs.readdirSync(url);
        if (files.length == 0) {
            fs.rmdirSync(url);
        }
        files.forEach(function (file, index) {
            // var curPath = url + "/" + file;
            var curPath = path.join(url, file);
            //fs.statSync同步读取文件夹文件,如果是文件夹,在重复触发函数
            if (fs.statSync(curPath).isDirectory()) { // recurse
                deleteAllFiles(curPath);
                // 是文件delete file
            } else {
                fs.unlinkSync(curPath);
            }
        });
        // 清除文件夹
        fs.rmdirSync(url);
    }
    // 调用方式
    // 存在目录
    // D--a--b--c--d--e--f--abc.txt
    //          |--h--r--n--abc.txt
    //          |--i--t--m--abc.txt
    //          |--j--y--k--abc.txt
    //          |--k--y--l--abc.txt
    mkdirsSync('D://a//b//c');
    // 结果只剩下D://a//b//c文件夹,内部内容全部清除。
    
    

    office操作

    其实上述API已经写了怎么调用和实现,并且连接内的API更加清楚,但是我们使用时常常会生成很多word每次都要重复写,所以封装了一个回调方法用来生成word,其他的可根据具体内容进行扩展。实现如下:

    /**
     * 导入数据并生成word。 
     * @param {导入的数据} data 
     * @param {导出路径} outPath 
     * @param {回到函数} callback 
     */
    function exportWord(data, outPath, callback) {
        var docx = officegen('docx');
        var pObj = docx.createP();
        pObj.addText(data);
        var out = fs.createWriteStream(outPath, { close: false });     // 文件写入
        out.on('error', function (err) {
            logger.info("exportWord error ! outPath : " + outPath, err);
        });
        docx.generate(out);
        out.on('close', function () {
            logger.info("exportWord success ! outPath : " + outPath);
            callback('callback');
        });
    }
    
    // 这样就不用写重复方法了,调用方式如下
    exportWord('balabalabala...', 'abc.docx', function () {    // 导出word文件abc.docx,word内容balabalabala...
        exportWord('balabalabala...', 'qwe.docx', function () {    // 导出word文件qwe.docx,word内容balabalabala...
            exportWord('balabalabala...', '123.docx', function () {    // 导出word文件123.docx,word内容balabalabala...
            // 回调中继续其他操作
            ...
            });
        });
    });
    
    

    总结

    上述内容只是常用的内容一部分,对于小白的我来说经常忘记,所以在此记录,互相学习,互相帮助。开发过程中还有其他形形色色的问题,后期再更新。

    欢迎关注我的博客我在马路边

  • 相关阅读:
    php递归无限分类、根据子类获取所有顶类
    PHP+Redis 有序集合实现 24 小时排行榜实时更新
    php操作redis常用方法代码示例
    Mysql 数据库默认值选 ''" 、Null和Empty String的区别
    linux查看端口占用情况
    php获取微信openid
    phpstorm 删除空行
    git常用操作命令归纳
    Redis数据类型
    渴求式加载指定字段、加载多个关联关系、嵌套的渴求式加载、带条件约束的渴求式加载
  • 原文地址:https://www.cnblogs.com/kerbside/p/9378584.html
Copyright © 2011-2022 走看看