http://www.blogjava.net/killme2008/archive/2007/09/27/148747.html
http://fair-jm.iteye.com/blog/1897875
Erlang用于操纵文件I/O的模块有:
file模块:打开、读、写、关闭文件已经操作目录的方法基本都在这里
filename模块:提供平台独立方式用于操纵文件名
filelib模块:file模块的扩展,提供了更多的实用工具,在file模块基础上构建
io模块:一系列用于操作打开的文件的方法,解析格式、格式化输出等等。
1.打开文件:
{ok,F}=file:open("data1.dat",read). %读模式打开
{ok,F}=file:open("data1.dat",write). %写模式
{ok,F}=file:open("data1.dat",[read,write]). %读、写、二进制模式
支持的所有模式参见文档。
2.读取:
(1)如果以一个Erlang term的方式读取,采用:
io:read(F,'').
其中第二个参数是提示符,用于在标准输入时作为提示。
这个方法有一个变形read/3
read(IoDevice, Prompt, StartLine)
第三个参数用于指定开始行数。
(2)如果是按字节读取,文件必须按raw模式打开采用:
{ok, Data}=file:read(F,100).
(3)按行读取:
io:get_line(F, '').
(4)读取整个文件的内容:
{ok,Binary}=file:read_file("data1.dat").
注意返回的是一个binary类型
(5)随机读取:
{ok,Binary}=file:pread(F, 22, 46).
其中第二个参数是开始位置,第三个参数是读取的长度,返回的也是binary类型。
3.写入文件:
(1)采用io:format/3方法:
{ok, S} = file:open("test2.dat", write).
io:format(S, "~s~n", ["Hello readers"]).
io:format(S, "~w~n", [123]).
其中的~开头的字符是一个个格式化命令,比如常见的:
~c anscii码
~f 浮点数
~s 字符串
~w Erlang term
~p 与~w类似,不过当多行时将自动换行
~n 显然,换行符
(2)写入整个文件:
file:write_file(File, IO)
其中IO可以为list、integer或者binary类型
(3)随机写入:
file:pwrite(F, 10, <<"new">>)
4.关闭文件:
file:close(F).
5.目录操作:
都是linux命令风格的操作,
cd("/home/dennis/"). %进入目录
file:list_dir("."). %列出当前目录文件
file:make_dir("test"). %创建test目录
file:del_dir("test"). %删除test目录
6.获取文件信息,比如文件大小,最后修改时间等等。调用file:read_file_info/1方法,该方法返回一个file_info记录类型,里面拥有文件的具体信息,比如type、size等。
{ok, Facts} =file:read_file_info(File).
io:format("~s~n",{Facts#file_info.type, Facts#file_info.size}).
7.复制和删除文件:
file:copy(Source, Destination).
file:delete(File).
这个笔记仅仅记录了一些常用到的方法,一些高级的工具方法并没有涉及,具体参考Erlang的文档。
erlang关于文件操作的模块还是很多的
stdlib下有filelib filename和file_sorter
核心模块有file 当然io的一些导出函数也可以用来对文件进行读写
这里简要记下笔记
首先是filelib
- 9> ls().
- doc factorial.beam factorial.erl
- fibo.beam fibo.erl head_test.hrl
- iotest.beam iotest.erl message.beam
- message.erl procedure.beam procedure.erl
- recode_test.beam recode_test.erl show_ip.beam
- show_ip.erl \x{6D4B}\x{8BD5}.txt
- ok
- 10> filelib:ensure_dir("doc").
- ok
- 11> filelib:ensure_dir("cc").
- ok
文档中解释是返回ok代表在在所有的父目录中存在或可以创建这个以输入为文件名的文件或者文件夹
错误的话返回{error, Reason}代表不存在也不能被创建
file_size/1 返回对应文件的字节数
is_dir/1 返回是否是目录
is_file/1 返回是否是文件(非目录)
is_regular 返回是否是正常文件(?)
last_modified/1 返回对应文件最后修改时间
wildcard 显示匹配通配符的文件的文件名
这些使用起来都很简单 就写一个例子:
- 33> filelib:fold_files(".",".*.erl",false,fun(Name,X) -> io:format("~20s ~p ~p ~p ~n",[Name,filelib:file_size(Name),filelib:last_modified(Name),fil
- elib:is_file(Name)]) end,0).
- ./factorial.erl 84 {{2013,6,22},{23,46,56}} true
- ./fibo.erl 195 {{2013,6,22},{22,59,39}} true
- ./iotest.erl 140 {{2013,6,23},{0,36,29}} true
- ./message.erl 805 {{2013,6,23},{15,45,51}} true
- ./procedure.erl 383 {{2013,6,25},{19,17,27}} true
- ./recode_test.erl 180 {{2013,7,1},{12,53,22}} true
- ./show_ip.erl 180 {{2013,6,28},{15,18,35}} true
- ok
以上代码对中文支持不行(不会显示中文 会打出string的list 所以那个~20s应该换为~p比较合适) 不会打印出文件夹(要全部打印可以通过wildcard匹配*之类的完成)
文件夹的is_file/1返回的也是true 而不是false 要判断直接用is_dir/1
filename的doc里密密麻麻都是例子我就懒得自己动手了...
file模块的操作不怎么麻烦
举几个例子:
文件夹建立删除:
- 59> file:del_dir("cc").
- ok
- 60> file:make_dir("cc").
- ok
读取文件:
可以用read_file/1 指定一下文件路径和文件名一口气读完 也可以用read/2 用read/2之前要对文件进行open操作获得IoDevice:
- 64> {ok,File}=file:open("fibo.erl",[raw,read]).
- {ok,{file_descriptor,prim_file,{#Port<0.538>,728}}}
- 65> {ok,Data}=file:read(File,filelib:file_size("fibo.erl")).
- {ok,"-module(fibo).\r\n-export([fibo/1]).\r\n\r\n%% fibo(1) -> 1;\r\n%% fibo(2) -> 1;\r\n%% fibo(N) -> fibo(N-1)+fibo(N-2).\r\n\r\nfibo(N) when N>
- 0 ->\r\n case N of\r\n 1 ->1;\r\n 2 ->1;\r\n _ ->fibo(N-1)+(N-2) end."}
- 66> Data.
- "-module(fibo).\r\n-export([fibo/1]).\r\n\r\n%% fibo(1) -> 1;\r\n%% fibo(2) -> 1;\r\n%% fibo(N) -> fibo(N-1)+fibo(N-2).\r\n\r\nfibo(N) when N>0 ->
- \r\n case N of\r\n 1 ->1;\r\n 2 ->1;\r\n _ ->fibo(N-1)+(N-2) end."
当然用完关一下..file:close(File).
写文件也一样简单:
- 70> {ok,File}=file:open("fibo.erl",[append]).
- {ok,<0.121.0>}
- 71> file.write(File,<<"hello 你好")>).
- * 1: syntax error before: '.'
- 71> file:write(File,<<"hello 你好")>).
- * 1: syntax error before: ')'
- 71> file:write(File,<<"hello 你好">>).
- ok
- 72> file:close(File).
- ok
注意open的参数有很多 这边不一一列举 file模块很多操作都和平台有关.
这边还有一个方便使用的read_line/1函数:
- 77> file:read_line(File).
- {ok,"-module(fibo).\n"}
- 78> file:read_line(File).
- {ok,"-export([fibo/1]).\n"}
- 79> file:read_line(File).
- {ok,"\n"}
- 80> file:read_line(File).
- {ok,"%% fibo(1) -> 1;\n"}
- 81> file:read_line(File).
- {ok,"%% fibo(2) -> 1;\n"}
- 82> file:read_line(File).
- {ok,"%% fibo(N) -> fibo(N-1)+fibo(N-2).\n"}
- 83> file:read_line(File).
- {ok,"\n"}
- 84> file:read_line(File).
- {ok,"fibo(N) when N>0 ->\n"}
- 85> file:read_line(File).
- {ok," case N of\n"}
- 86> file:read_line(File).
- {ok," 1 ->1;\n"}
- 87> file:read_line(File).
- {ok," 2 ->1;\n"}
- 88> file:read_line(File).
- {ok," _ ->fibo(N-1)+(N-2) end."}
- 89> file:read_line(File).
- eof
- 90> file:read_line(File).
- eof
不太友好返回了个\n可以用正则处理掉 \\n$