[Erlang19]Erlang的config文件读取效率问题

Erlang配置文件的几种选择:
 
方法
优点
缺点
1.把配置文件统一读取到存储介质中(ets表或mysql)
统一管理,可以方便跨节点分布Reload,
Erlang Application就是把configuration 文件给读到一个叫ac_tab 的ets表
如果频繁大量的读取这个全局表,要考虑表的性能哦
2.把配置文件做为*.xml或*.config,用Erlang直接读取xml或config
配置成xml,会方便配置人员(前后端都是xml,容易上手)
配置成config,Erlang读取程序很简单
Erlang不适合读取xml
频繁去读一个硬盘文件明显非常不好
3.把配置文件转化为*.beam文件
查询效率高
几乎没有,当然除了分布式部署有点复杂,可是这功能又没什么用
 
于是乎:自己做一个配置转化(欢迎找Bug,费尽心思你也找不到,因为这代码本来没有Bug,哈哈) :
你只要把config放到指定好文件的路径就可以使用:
%%转化get_config_dir()下所有的config文件
%%可检查各config文件的格式是不是key重复或格式是不是{key,Value}
1>configToBeam:config_to_beam().
check Config syntax error"test_duplicate_error.config":Reason:{error,
                                                               key_duplicate,
                                                               1}
check Config syntax error"test_format_error.config":Reason:{error,
                                                            format_error,
                                                            {2,3,test2}}
[{ok,test_best},
 {error,"test_duplicate_error.config"},
 {error,"test_format_error.config"}]
%%返回所有的{key,Value} 2>test_best:all(). [{4,test4},{3,test3},{2,test2},{1,test}] %%返回对应Key的Value 3>test_best:lookup(2). test2 %%如果不存在Key则返回undefined 4>test_best:lookup(12). undefined
我的测试数据目录放在
  
1 code:root_dir()++"/config"
2 
3 %%里面有4个文件:
4 %%test.txt 不以config的文件检查跳过
5 %%test_best.config 这个是正常配置
6 %%test_format_error.config 不是{key,Value}的配置
7 %%test_duplicate_error.config Key有重复的配置

 

源代码如下:
  1 %%%-------------------------------------------------------------------
  2 %%% @author zhongwencool@gmail.com
  3 %%% @doc   把对应的.config文件转为.beam文件并更新到内存
  4 %%%        configName:all()       return all key_value
  5 %%%        configName:lookup(Key) return value or undefined
  6 %%% 1.得到目录下文件集合
  7 %%% 2.遍历对每个文件进行转换
  8 %%%   2.1 把文件读入 检查格式
  9 %%%   2.2 把config转化为erl文件
 10 %%%   2.2 把erl文件编译成beam文件
 11 %%% 3.加载beam文件到内存
 12 %%% @end
 13 %%% Created : 22. Aug 2014 4:08 PM
 14 %%%-------------------------------------------------------------------
 15 -module(configToBeam).
 16 
 17 -compile(export_all).
 18 %% API
 19 -export([config_to_beam/0,config_to_beam/1,get_config_dir/0]).
 20 
 21 %% @doc 把指定目录下全部的config文件都转为.beam文件并加载到内存
 22 config_to_beam() ->
 23     AllConfigName = get_all_config_name(),
 24     [begin
 25          config_to_beam(ConfigName)
 26      end||ConfigName <- AllConfigName].
 27 
 28 %% @doc 把指定目录下名为ConfigName的config文件转为.beam文件并加载到内存
 29 config_to_beam(ConfigName) ->
 30     case check_syntax(ConfigName) of
 31         {ok, TermList}  ->
 32             term_to_beam(ConfigName -- ".config", TermList);
 33         Reason ->
 34             io:format("check Config syntax error~p:Reason:~p~n",[ConfigName, Reason]),
 35             {Reason,ConfigName}
 36     end.
 37 
 38 %% @todo 改成你存放.config文件的目录
 39 get_config_dir() ->
 40     code:root_dir()++"/config".
 41 
 42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 43 %%%  Internal Function
 44 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 45 term_to_beam(ModuleName,TermList) ->
 46     Erl = term_to_erl(ModuleName,TermList),
 47     ModuleName2 = ModuleName++".erl",
 48     file:write_file(ModuleName2, Erl, [write, binary, {encoding, utf8}]),
 49     compile:file(ModuleName2),
 50     ModuleName3 = list_to_atom(ModuleName),
 51     code:purge(ModuleName3),
 52     code:load_file(ModuleName3),
 53     {ok,ModuleName3}.
 54 
 55 term_to_erl(ModuleName,TermList) ->
 56     StrValue = lists:flatten(term_to_erl2(TermList,"")),
 57     StrList = lists:flatten(io_lib:format("     ~w\n", [TermList])),
 58     "
 59     -module(" ++ ModuleName ++ ").
 60     -export([all/0,lookup/1]).
 61 
 62     all()->"++ StrList ++".
 63 
 64     lookup(Key) ->
 65       case Key of
 66         " ++ StrValue ++ "
 67         _ -> undefined
 68     end.
 69 ".
 70 
 71 term_to_erl2([],Sum) ->
 72     Sum;
 73 term_to_erl2([{Key, Value}|Left],Acc) ->
 74     term_to_erl2(Left,
 75         io_lib:format("       ~w -> ~w;\n",[Key, Value])++Acc).
 76 
 77 get_all_config_name() ->
 78     {ok,AllFileName} = file:list_dir(get_config_dir()),
 79     lists:filter(fun(FileName) ->
 80         case lists:reverse(FileName) of
 81             "gifnoc." ++_ -> true;
 82             _ -> false
 83         end
 84     end,AllFileName).
 85 
 86 check_syntax(ConfigName) ->
 87     case file:consult(joint_path(ConfigName)) of
 88         {ok, TermList = [_|_]} ->
 89             check_fromat_duplicate(TermList, []);
 90         Reason ->
 91             {error, Reason}
 92     end.
 93 
 94 joint_path(ConfigName) ->
 95     get_config_dir() ++"/" ++ ConfigName.
 96 
 97 check_fromat_duplicate([], Acc) ->
 98     {ok, Acc};
 99 check_fromat_duplicate([{Key, _Value} = Term|Left], Acc) ->
100     case lists:keymember(Key, 1, Acc) of
101         true -> {error, key_duplicate, Key};
102         false -> check_fromat_duplicate(Left, [Term|Acc])
103     end;
104 check_fromat_duplicate([Term|_],_Acc) ->
105     {error,format_error,Term}.

 

             生活好艰辛可是老子就是这么萌 ^^

posted @ 2014-08-23 11:30  写着写着就懂了  阅读(2611)  评论(0编辑  收藏  举报