您的位置:首页 > 其它

erlang 备忘

2016-05-27 15:51 351 查看
1.   a 是模块名:

     begin c(a,[debug_info]), im(), ii(a), iaa([init]) end.

    用于调试数据。

1.1 常用list, tuple 方法

     List = [one,two,three].

     tl(List).

     hd(List).

     lenght(List).

   

    Tuple = [1,2,3,4,5].

    tuple_size(Tuple).

    element(2,Tuple).

    setelement(3,Tuple,three).

    erlang:append_element(Tuple, 6).

2. 字符串格式化

2.1
%% ~c 表示只接受 ASCII 码所表示的数字
%% ~f 表示浮点数输出,默认保留 6 为小数
%% ~w 表示输出一个 Erlang term
%% ~p 与 ~w 类似,不过 ~p 的输出是有格式的,默认一行的显示的最大长度为80,则多行时会自动换行
%% ~s 表示按字符串形式输出
%% ~n 表示换行符
%% ~ts表示translation string,用来显示unicode,支持中文
format(Format, Args)->
lists:flatten(io_lib:format(Format,Args)).

mytest() ->
Cmd = format("select user_id from users where device_id=~s;",["abc"]).

% 结果:select user_id from users where device_id=abc;

2.2 进程字典的使用:
A = [{"t","reg"},{"a","123"},{"b","456"}],
C = ets:new(xx,[set]),

B = lists:foreach(
fun(X) ->
{P,V} = X,
io:format("ff:~p~p~n",[P,V]),
erlang:put(P,V)
end, A ),

% 得到所有并删除
Li = erlang:erase(),
% 看年是不是空了
Li2 = erlang:get().

2.3 erlang des 加密测试
B5 = crypto:block_encrypt(des_cbc, "12345678", <<0:64>>, "87654321").
%<<56,84,48,40,155,117,148,36>>
crypto:block_decrypt(des_cbc, "12345678", <<0:64>>, B5).
%<<"87654321">>
%//////////////////
encrypt(Text) ->
crypto:start(),
encrypt_chunk("12345678", list_to_binary(Text)).

encrypt_chunk(PassWord, BinTex) when byte_size(BinTex) >= 8 ->
{Chunk, Rest} = split_binary(BinTex, 8),
<< (crypto:block_encrypt(des_ecb, PassWord, Chunk))/binary, (encrypt_chunk(PassWord, Rest))/binary >>;

encrypt_chunk(PassWord, <<>>) ->
crypto:block_encrypt(des_ecb, PassWord, <<0:64>>);

encrypt_chunk(PassWord, BinTex) ->
PadSize = (8 - byte_size(BinTex)) * 8,
PadBin = <<BinTex/binary, 0:PadSize>>,
crypto:block_encrypt(des_ecb, PassWord, PadBin).

decrypt(BinTex) ->
binary_to_list(decrypt("12345678", BinTex)).

decrypt(PassWord, BinTex) when byte_size(BinTex) >= 8 ->
{Chunk, Rest} = split_binary(BinTex, 8),
case Rest of
<<>> ->
Result = crypto:block_decrypt(des_ecb, PassWord, Chunk),
delete_pading(Result);
_ ->
<< (crypto:block_decrypt(des_ecb, PassWord, Chunk))/binary ,(decrypt(PassWord, Rest))/binary >>
end;
decrypt(PassWord, BinTex) ->
Result = crypto:block_decrypt(des_ecb, PassWord, BinTex),
delete_pading(Result).

delete_pading(<<0:64>>) ->
<<>>;
delete_pading(<<A, 0:56>>) ->
<<A>>;
delete_pading(<<A, B, 0:48>>) ->
<<A, B>>;
delete_pading(<<A, B, C, 0:40>>) ->
<<A, B, C>>;
delete_pading(<<A, B, C, D, 0:32>>) ->
<<A, B, C, D>>;
delete_pading(<<A, B, C, D, E, 0:24>>) ->
<<A, B, C, D, E>>;
delete_pading(<<A, B, C, D, E, F, 0:16>>) ->
<<A, B, C, D, E, F>>;
delete_pading(<<A, B, C, D, E, F, G, 0:8>>) ->
<<A, B, C, D, E, F, G>>;
delete_pading(Binary) ->
Binary.
////

% test decode
Bret = base64:decode_to_string("AbIHxAf2Vn3fs5VQDpqLDg=="),
Bret2 = list_to_binary(Bret),
%Ds = encrypt("123456789"),
Ds2 = decrypt( Bret2 ),


2.4
base64 erlang 实现
10>base64:encode_to_string("Base64测试").
"QmFzZTY0suLK1A=="
11>base64:decode_to_string("QmFzZTY0suLK1A==").
"Base64测试"
12>base64:decode_to_string("QmFzZTY0suL %^K1A==").
** exception error: no function clause matchingbase64:b64d_ok(bad) (base64
line 363)
in function base64:decode/2(base64.erl, line 264)
13>base64:mime_decode_to_string("QmFzZTY0suL K1A==").
"Base64测试"
14>base64:mime_decode_to_string("QmFzZTY0suL %^ K1A==").
"Base64测试"
2.5 url 编码和解码
34> End = http_uri:encode("luca+more@here.com").
"luca%2Bmore%40here.com"
35> http_uri:decode(End).
"luca+more@here.com"

3. erlang 命令行 (转坚强2002 )

平时调试代码最比较郁闷的一个问题就是Erlang Shell一旦关闭刚刚输入过的命令历史就丢失了,如果能像维护一个输入命令的历史就方便了;下面的这一个项目就可以帮我们解决这个问题:

Projects / rlwrap

rlwrap

 rlwrap is a readline wrapper, a small utility that uses the GNU readline library to allow the editing of keyboard input for any other command. It maintains a separate input history for each command, and can TAB-expand words using all previously seen words
and/or a user-specified file.

我的系统是Centos 5.6,安装方法如下:

wget 'http://utopia.knoware.nl/~hlub/rlwrap/rlwrap-0.37.tar.gz'
tar zxf rlwrap-0.37.tar.gz
cd rlwrap-0.37
./configure
make install


 注意:可能会提示缺少readline库,使用下面命令安装

 yum install readline-devel 


设置别名方便使用

 vi ~/.profile

添加别名
alias erl='/data/rlwrap/rlwrap-0.37/src/rlwrap -a  erl'
保存退出

重新加载别名
source ~/.profile
 
运行erl 输入几次关闭,再运行erl,试试上下箭头是不是刚刚输入的命令都还在?!

 
 还有好多Linux下的好工具等着我去挖掘呢,Go!

Mac上边有个简单的就是erlang-history
https://github.com/ferd/erlang-history
用sudo make install 安装就可以了,方便的很。

4. json 处理  节点的获取和对象删除

      
test_dict()
->
 Dict
= dict:append("c",2,
 dict:append("c",1,
 dict:store("b",
<<"hello">>,
 dict:store("a",123,dict:new())))),
 {ok,
Obj, ""}=rfc4627:decode(rfc4627:encode(Dict)),
 {ok,
123} =
rfc4627:get_field(Obj,"a"),
 {ok, <<"hello">>}=rfc4627:get_field(Obj,"b"),
 {ok, [1,2]}=rfc4627:get_field(Obj,"c"),
 passed.
  
 test_exclude()
->
 Dict
= dict:store("c",2,
 dict:store("b",
<<"hello">>,
 dict:store("a",123,dict:new()))),
 {ok,
Obj, ""}=rfc4627:decode(rfc4627:encode(Dict)),
 Obj2
= rfc4627:exclude_field(Obj,"a"),
 true
= rfc4627:equiv({obj, [{"c",2},
{"b", <<"hello">>}]},Obj2),
 Obj3
= rfc4627:exclude_field(Obj2,"b"),
 true
= rfc4627:equiv({obj, [{"c",2}]},Obj3),
 Obj4
= rfc4627:exclude_field(Obj3,"x"),
 true
= rfc4627:equiv({obj, [{"c",2}]},Obj4),
 Obj5
= rfc4627:exclude_field(Obj3,"c"),
 true
= rfc4627:equiv({obj, []},Obj5),
 passed.
% Out2 = <<rtmp://pili-publish.alisports.com/alisports/5746713c75b6255cf102cb00?key=ec0c67a6-22b7-4a80-a7cc-f59bd53f3a97>>
S = xmerl_ucs:from_utf8(Out2),
结果 S: rtmp://pili-publish.alisports.com/alisports/5746713c75b6255cf102cb00?key=ec0c67a6-22b7-4a80-a7cc-f59bd53f3a97


5. json   处理

josn.erl:文件和xmerl_ucs.erl文件
Example 4-4. Generating the content

do(Q)->

 F = fun() ->

 qlc:e(Q) end,

 {atomic, Value} = mnesia:transaction(F), Value.

convert_to_json(Lines) ->

  Data = [{obj,

  {airport, Line#airport.code},

  {city, Line#airport.city},

  {country, Line#airport.country},

  {name, Line#airport.name}]}

  || Line <- Lines],

  JsonData = {obj, [{data, Data}]}, rfc4627:encode(JsonData).

handle('GET', _Arg) ->

   io:format("~n ~p:~p GET Request ~n", [?MODULE, ?LINE]),

   Records = do(qlc:q([X || X <- mnesia:table(airport)])),

   Json = convert_to_json( Records),

   io:format("~n ~p:~p GET Request Response ~p ~n", [?MODULE, ?LINE, Json]), {html, Json};

Example 4-5. Generating the content (pretty printed)

{

"data": [

    {

    "airport": "BOS", "city": "Boston", "country": "US", "name": "Logan"

    },

    {

    "airport": "JFK", "city": "New York", "country": "US",

"name": "John F Kennedy"

    } ]

}

% 返回数组的处理

%{"data":[{"name":"a","age":12},{"name":"b","age":15}]}
myjson()->
Data = [{obj,[{name, <<"a">>}, {age, 12}]},
{obj, [{name,<<"b">>}, {age, 15}] }],

JsonData = {obj, [{data, Data}]},
Ret = rfc4627:encode(JsonData),
Ret.


% 简单串生成

% {"items":{"c":2,"b1":"d1"}}

mytest() ->
Dict = dict:store("c", 2,
dict:store("b", <<"hello">>,
dict:store("a", 123, dict:new()))),

{ok, Fobjd, ""} = rfc4627:decode(rfc4627:encode(Dict)),
Nj = rfc4627:encode( Fobjd ),

Fobj = {obj,[]},
Fobj2 = rfc4627:set_field( Fobj, "items", {obj,[{"c",2 },{"b",<<"d">>}]} ).


6.  类型转化

比较纠结于数据类型转换,所以要经常熟悉看看

1> atom_to_list(hello).
"hello"
2> list_to_atom("hello").
hello
3> binary_to_list(<<"hello">>).
"hello"
4> binary_to_list(<<104,101,108,108,111>>).
"hello"
5> list_to_binary("hello").
<<104,101,108,108,111>>
6> float_to_list(7.0).
"7.00000000000000000000e+00"
7> list_to_float("7.000e+00").
7.0
8> integer_to_list(77).
"77"
9> list_to_integer("77").
77
10> tuple_to_list({a,b,c}).
[a,b,c]
11> list_to_tuple([a,b,c]).
{a,b,c}
12> term_to_binary({a,b,c}).
<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>
13> binary_to_term(<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>).
{a,b,c}


 7. erlang 数据项写入到文件当中,并且读取出来:

% 注意 ~p 后边的. 不能少。
unconsult(File, L) ->
{ok, S} = file:open(File, write),
lists:foreach(fun(X) -> io:format(S, "~p.~n",[X]) end, L),
file:close(S).

% 调用 ////////////////////////

unconsult("a.tt", [{"1","2","3"}]),
{ok,S} = file:consult( "a.tt" ),
[{A,B,C}] = S.
//////////////////////////////

8. erlang 启动后脱离控制台的方法

erl启动使用  -detached 参数启动

这个参数可以让erl节点脱离了终端。

例如 :   $erl -sname dp -detached

如何链接:
erl -sname dp2 -remsh dp@dp0304

如何退出:!!!超级要注意啊~~不能直接关掉退出

   ctrl +g 进入JCL模式

   输入  q  回车
 
9.  erlport 的使用。
test()->
{ok, P1} = python:start([{python_path, "/home/yangzm/tmp"},{python,"python2.7"}]),

% 用try catch 捕获异常
try
A = python:call(P1, a, add2, ["aa","bb",22,55]),
error_logger:info_msg("~w~n",[A])
catch
error:{python, Class, Argument, StackTrace} -> error
% _:_ -> error  // catch all errors
 end,
python:stop().%结束

# python
import sys
def version():  
 return sys.version
def get():
return [1,2,3]
def get2():   
return ["this", "is", "a", "test"]
def add(a,b):  
 return a+b
def add2(a,b,c,d):   
return [a,b,c,d]
  

10.  copy 文件夹操作

-module(filemanager).  
%% ====================================================================  
%% API functions  
%% ====================================================================  
  
-export([startCopy/0]).  
  
startCopy() ->  
    FromDir="E:/workspace/HelloWorld/cmd",  
    TarDir="E:/workspace/HelloWorld/cmd_copy",  
    copyDir(FromDir,TarDir).  
  
%%拷贝文件夹 FromDir要拷贝的文件夹路径 TarDir 拷贝到的目标文件夹  
copyDir(FromDir,TarDir)->  
      
    %%获取当前文件夹的所有文件列表(包括子文件夹)  
    {ok,AllFile} = file:list_dir_all(FromDir),  
    %%创建目标文件夹  
    file:make_dir(TarDir),  
    %%尾递归遍历所有文件  
    loopCopy(AllFile,FromDir,TarDir).  
  
loopCopy(AllFile,FromDir,TarDir) ->  
    case AllFile of  
        [] ->  
            ok;  
        _ ->  
            %%每次拿第一个文件  One  
            [One|Other]=AllFile,  
            Path=FromDir++"/"++One,  
            Tar=TarDir++"/"++One,  
            %%判断当前文件是否是文件夹  
            IsDir= filelib:is_dir(Path),  
              
            %%if写法  所有判断的可能写在前面  true写在后面  
            if IsDir =:= false->  
                   %%如果当前是文件  则拷贝到目标路径  
                   file:copy(Path, Tar);  
               %%if 的默认值  
               true->  
                   %%如果当前是文件夹 在目标路径创建文件夹  并拷贝当前文件夹  
                   file:make_dir(Tar),  
                   copyDir(Path,Tar)  
            end,  
  
            %%递归第一个文件后面的文件  
            loopCopy(Other,FromDir,TarDir)  
    end. 

11  get module path

   

{ModPath, _} = filename:find_src(?MODULE),
AppPath = filename:dirname(filename:dirname(ModPath)),
Path = filename:join(AppPath, "priv"),


Str1 = filename:dirname( code:which( ?MODULE ) ),
{ModPath, _} = filename:find_src(?MODULE),
Path = filename:join(Str1, "priv"),
error_logger:info_msg("~w",[Path]).

12.  目录,文件是否存在
1.
{Ret,_} = file:read_file_info( "/home/yangzm/test" )
如果存在返回ok,不存在就是error。
这个函数内部有捕获异常的处理,所以外部不用再处理了,这里的参数最后的斜杆,"test" 和 "test/"这两种写法,最后调用后结果是
一样的结果,都可以。
 2.
filelib:ensure_dir(some dir...) 这个函数可以产生不存在的目录和文件。
要注意就是如果是要产生目录最后一个“/” 要加上,否则就出错
filelib:ensure_dir("/tmp/abc"), 要写成 filelib:ensure_dir("/tmp/abc/").
否则产生的目录是没有abc 文件夹的。

13.

ubuntu下erlang man的安装

下载 http://www.erlang.org/download/otp_doc_man_18.1.tar.gz 找到erlang 安装目录 
解压 otp_doc_man_18.1.tar.gz
sudo cp -r man /usr/local/lib/erlang
erl -man lists 查看结果

14. 元祖排序
1> lists:reverse(lists:keysort(2, [{a,2}, {b,1}, {c, 3}])).
[{c,3},{a,2},{b,1}]
2> lists:keysort(2, [{a,2}, {b,1}, {c, 3}]).               
[{b,1},{a,2},{c,3}]
3> lists:sort(fun(A, B) ->
3>
3>                    {_, A2} = A,
3>
3>                    {_, B2} = B,
3>
3>                    A2 =< B2
3>
3>            end, [{a,2},{b,1},{c,3}]).
[{b,1},{a,2},{c,3}]
4>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  erlang