erlang的配置文件加载

       现在游戏需要你做一个物品强化的功能,不说逻辑的问题,这个时候我们一定会想到一个问题,那就是在功能已经实现的情况下,这些数据从哪得到,三种情况1数据库  2ets表  3配置文件!

      1数据库 么如果是存储在数据库里,结果就是我们每次进行一个简单的强化操作,我们读一次数据库,这样是完全不可取的,因为太影响速度先不管数据量是否大,检索算法有多快,并发数量有多高的问题,光是中间的调度问题就不可小觑,小一点的游戏数据库和系统在同一个服务器上可能还好一些,如果是在不同的服务器上就废废了,如果再赶上玩家多,并发量大,对数据库的操作特别多那就更慢了!但是即便不可取我们也还是要考虑一下是否这样有优点,当我们手动更改了配置文件的时候,配置数据的更新就是实时的,也就是说我们不用停止服务器,数据就可以更新上去!

       2配置文件 那么如果是直接使用配置文件呢?这个时候我们都是打开一个输入输出流来操作,erlang里提供了一个file模块专门来处理这类问题,还是强化装备,这个时候要获取数据,那么我们打开了一个文件拿到数据进行操作,你可能感觉这样会更快一些,其实不然,文件其实就是硬盘存储的方式,小数据量的文件确实没有什么影响,但是如果是同时多人强化,读取配置文件,那就真的是麻烦到家了!

       3ets表 

       前两种都不行,那我们怎么办,这时候要考虑的是内存存储了,erlang里一提到内存存储我们首先想到的就是ets,而且可以保证进程间共享内存,使用他来操作再不合适不过了,无论是配置表还是数据库读出来的数据我们都可以加载到内存里,然后直接去读取内存,这种方式很高效,解决了我们的需求

       先看一下file模块的加载方法

consult(Filename) -> {ok, Terms} | {error, Reason}  %%Filename要包含路径切记
   那么我们来做一个简单的读取配置文件并加载的小程序!!!先做一个简单的配置文件streng.config

   

{a, 11,22}.
{b, 11,22}.
{c, 11,22}.
{d, 11,22}.
{e, 11,22}.
{f, 11,22}.
 

 

 

-module(streng)
-export([load/1]).
-define(?STRENG_FILE,        "../streng.config").
load() ->
	{ok, Data} = file:consult(STRENG_FILE),
	case ets:info(?MODULE) of
		undefined ->
			ets:new(?MODULE, [set, public, named_table,{read_concurrency, true}]);
		_Other ->
			ok
	end,
	lists:foreach(fun(SingleData) ->
		case Key of
			{} ->
				none;
			 _ ->
				true = ets:insert(?MODULE, Key)
		 end
	end, Data),
	ok.
    这样我们就写了一个简单的像ets里加载配置文件的方法,值得注意的是,ets加载的位置是你调用方法的进程内存里,这样的加载方式是直根据你的配置表的主键向ets里加载,如果你想要根据得到这些数据也是要根据主键去查找的(这里使用第一个字母列为主键)
    下面是查找我们存到ets里的数据
get_data(Key) ->
	Result = ets:lookup(?MODULE, Key),
	case Result of
		[] ->
			{};
		[Data] ->
			Data
	end.

get_Second(Data) ->
	erlang:element(2, Data).     %%你可以看看文档,这个方法是做什么用的,虽然现在你可能已经明白了
get_Third(Data) ->
        erlang:element(3, Data).
       这里我们完整的完成了我们的工作,这只是简单的操作,这样做并不美观,也不便于理解,更重要的是,这么做很不直观,配置文件的内容也没有显示出来,当有一天一个新的程序猿来修改你的代码的时候,他很难从你的代码里了解你的配置文件内容,还有一点就是ets存储的也只是很普通的一组组数据如果有必要去看ets的话,我们也完全不了解我们存的是什么,当一个进程存储了大量的配置文件信息的时候,依靠这种方式,我们很难通过UI去了解到底这个进程里存了那些东西,借此我们利用record重新写一下这个方法!
-module(streng)
-export([load/1]).
-define(?STRENG_FILE,        "../streng.config").‘
-record(streng,{
               id,
               num,
               count
}).%%这个record只是我随便定义的名称
load() ->
	{ok, Data} = file:consult(STRENG_FILE),
	case ets:info(?MODULE) of
		undefined ->
			ets:new(?MODULE, [set, public, named_table,{read_concurrency, true}]);
		_Other ->
			ok
	end,
        %%重点在这里,加载一个将数据封装与record里加载到ets中
	lists:foreach(fun(SingleData) ->
		{Id, Num, Count} =  SingleData,%%匹配单条数据到你的变量里
                StrengSingleData = #streng{
                                           id = Id,
                                           num = Num,
                                           count = Count
                                   },
                true = ets:insert(?MODULE, {Id, StrengSingleData })%%这里以id为主键插入相应的数据
	end, Data),
	ok.
       这样看是不是感觉更为直观,如果你在record后面加上相应的注释,你的整个加载方法就能体现出配置文件的内容了,便于后期他人的查阅和维护,那么我们在来看以下这种方法的时候取数据应该怎么做
get_data(Key) ->
	Result = ets:lookup(?MODULE, Key),
	case Result of
		[] ->
			{};
               %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		[Data] ->
			Data          %%我们可以换一种取法,因为这时这样直接取Data已经没有太多的意义了,我们可以直接返回总的数据而不要主键信息(如下)
               %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                [{Id, Info}] ->
                        Info
	end.

get_Second(Info) ->
	Info#streng.num.
get_Third(Data) ->
        Info#streng.count.
        
       这样的一个简单的配置文件加载到ets的读取操作就算完成了,举一反三,如果是数据库的操作我们也可以按照这个方法,不管你是用的是Menisa还是其他的数据库,都可以依照这个方式来加载到ets,只不过是改变一下数据读取方式,方法是相通的唯一不同的是数据的来源。
       那么我们如果修改了配置文件怎么办,而我现在又不想关掉服务器重新加载?那么就可以单独写一个模块,去调用loading()方法,我们在控制台也好,或者依靠其他方式也罢,直接调用即可,那么ets就会被重写,很多公司也会根据自己的需求去写一个类似的动态加载脚本,这里我们就不多说了
       当然,到了最后还是要顺带说一句,我们一般的情况下都是在启动节点的时候就将这类的配置文件加载到相应的进程里了(你可以参想一下,gen_server或者superviours的init()回调函数,我们在init里来处理加载问题),在每一个节点会有一个单独的进程专门存储这类配置文件,由于我们设置的ets格式是可以在进程间共享的,所以这类公共资源文件就很容易被各种方法调用,很是方便!

 

      

       

      

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值