[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}.
生活好艰辛可是老子就是这么萌 ^^
写下来是好习惯: Notes