[Erl_Question19]Erlang的config文件读取效率问题 - 学贵有恒

时间 2014-08-23 11:30:00  博客园-原创精华区


方法
优点
缺点


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}.


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