zoukankan      html  css  js  c++  java
  • nodejs简单层级结构配置文件

    在NodeJS中使用配置文件,有几种比较不错的方案:
    第一种:文件格式使用json是毋容置疑的好方案。格式标准,易于理解,文件内容读取到内存之后,使用JSON的标准分析函数即可得到配置项。
    第二种:将配置文件做成模块。其内容格式完全可以整合成一个object,然后将其导出。在NodeJS中require引入后,可以直接访问配置项。
    第三种:使用Ini格式或者类XML的配置文件。这样的配置文件后台开发司空见惯,格式清晰,也不失是一种比较好的方法。

    由于最近一个项目需要在NodeJS中读取分析后台生成的类XML配置文件,所以凑周末时间写了一个简单层级配置文件的解析类。封装后发布到npmjs,供有需要的同学一起使用。01.简单层级配置文件格式
    //定义主配置文件
    <main>
        <log>
            filepath = /data/app/logs
            filename = svrrequest.log
        </log>
    
        //定义可用的服务端IP地址
        <server>
            <ipinfo>
                host = 192.168.10.58
                port = 28000
            </ipinfo>
    
            <ipinfo>
                host = 192.168.25.26
                port = 14000
            </ipinfo>
        </server>
    </main>
    
    //定义MySQL数据库访问用户和密码
    <mysql>
        user     = admin
        password = admin@*123456%
    </mysql>
    
    //定义告警接收人邮件地址
    email = motadou@126.com
    
    02.使用方法 首先使用npm安装该配置文件解析模块:
    npm install mo-configure
    
    获取配置项的语法如下:
    //第一步,引入配置文件解析类
    var configure = require("mo-configure");
    
    //第二步,创建一个配置文件解析类
    var config		= new configure();
    
    //第三步,指定配置文件路径,或者传入配置文件的内容
    //比如:
    //config.parseText('<main>email=motadou@126.com</main>')
    //config.get("main.email");
    config.parseFile("main.conf");
    
    //例子一: configure to json
    //json为内置属性,该属性将配置文件内容转换成了JSON格式的数据
    console.log(config.json);
    
    //例子二:有两种方法获取指定的配置项
    //第一种直接访问内部的JSON结构,但这种方法有时会抛出异常,请注意捕捉
    console.log(config.json.email);
    console.log(config.json.main.log.filename);
    
    //第二种调用配置类的get函数,该函数当找不到配置项时,允许返回一个指定的默认值
    console.log(config.get("email", "not define email"))
    console.log(config.get("main.log.filename"));
    
    //例子三:返回一个JSON对象
    var ipinfo = config.get("main.server.ipinfo");
    console.log(ipinfo);
    03.配置文件类的实现 源代码以及后续更新请参考Github项目:https://github.com/motadou/mo-configure.git
    主要实现代码原理如下:
    var fs = require("fs");
    
    var configure = function () {
        this._data = { };
    
        this.__defineGetter__("json", function () { return this._data; });
    }
    
    configure.prototype.parseText = function (sText) {
        var arr   = sText.split(/
    |
    |
    /); //行划分
        var stack = [this._data];
    
        for(var i = 0, len = arr.length; i < len; i++) {
            var line = arr[i].replace(/^[s	 ]+|[s	 ]+$/g, '');
            if (line.length == 0 || line[0] == "#") {
                continue;
            }
    
            //当前行为当前域下面的值
            if (line[0] != "<") {
                var options = line.split("=");
                var key     = options[0].replace(/^[s	 ]+|[s	 ]+$/g, '');
                var value   = options.length == 2?options[1].replace(/^[s	 ]+|[s	 ]+$/g, ''):undefined;
    
                stack[stack.length - 1][key] = value;
                continue;
            }
    
            //当前行为域的标识
            if (line[line.length - 1] != '>') {
                //域标识符有开头但没有结尾,则分析错误
                this.data = {};
                return false;
            }
    
            //当前行为域的结束
            if (line[1] == "/") {
                stack.pop();
                continue;
            }
    
            //当前行为域的开始
            var key     = line.substring(1, line.length - 1);
            var parent  = stack[stack.length - 1];
    
            if (parent.hasOwnProperty(key)) {
                //在当前域中已经有相同名字的域
                if (parent[key] instanceof Array) {
                    parent[key].push({});
                } else {
                    parent[key] = [parent[key], {}];
                }
                stack.push(parent[key][parent[key].length - 1]);
            } else {
                parent[key] = {};
                stack.push(parent[key]);
            }
        }
    }
    
    configure.prototype.parseFile = function (sFilePath, encoding) {
        var data = fs.readFileSync(sFilePath, encoding?encoding:"utf8");
    
        this.parseText(data);
    }
    
    configure.prototype.toJson = function() {
        return this._data;
    }
    
    configure.prototype.get = function (key, DEFAULT_VALUE) {
        key = key.replace(/[s	 ]+/g, '');
        key = key.replace(/.{2,}/g, '.');
    
        var paths  = key.split('.');
        var parent = this._data;
        for (var i = 0, len = paths.length; i < len; i++) {
            if (!parent.hasOwnProperty(paths[i])){
                return DEFAULT_VALUE;
            }
    
            if (i == len - 1) {
                return parent[paths[i]];
            }
    
            parent = parent[paths[i]];
        }
    }
    
    module.exports = configure;
  • 相关阅读:
    Nebula3的Input系统
    Nebula3学习笔记(7): 脚本系统
    项目经理成长日记(4)——态度决定一切
    Nebula3学习笔记(2): 核心库
    Nebula3学习笔记(1): 序
    魔兽争霸的地图验证漏洞和作弊图原理,兼谈魔兽联机机制[转载]
    Nebula3的多线程架构
    项目经理成长日记(5)——五指有长短,能力各不同
    Nebula3资源子系统
    Nebula3的场景管理
  • 原文地址:https://www.cnblogs.com/motadou/p/3886007.html
Copyright © 2011-2022 走看看