文件操作函数库的组织方式
• file 模块,打开关闭,读写,列目录,等等基本操作
• filename 模块,一致的处理不同平台上的文件名
• filelib 模块,是file模块的一个扩充,大多是用file模块的函数编写
• io 模块,提供一些函数来处理已打开的文件,比如分析文件内容,将格式化的数据写入文件等
读取文件的不同方式
• 文件内容都是由一些字节组成,这些内容是什么含义完全取决于怎么处理
• 例如文件:
{person, "joe" , "armstrong" ,
[{occupation, programmer},
{favoriteLanguage, erlang}]}.
{cat, {name, "zorro" },
{owner, "joe" }}.
• 1. 一次性读入所有的语句
• file:consult(FileName) 假设文件内包含有合法的erlang语法,成功返回{ok,[Term]},失败返回{error,Reason}
• 2. 一条一条的读出语句
1> {ok, S} = file:open("data1.dat", read).
{ok,<0.36.0>}
2> io:read(S, '').
{ok,{person,"joe",
"armstrong",
[{occupation,programmer},{favoriteLanguage,erlang}]}}
3> io:read(S, '').
{ok,{cat,{name,"zorro"},{owner,"joe"}}}
4> io:read(S, '').
eof
5> file:close(S)
• @spec file:open(File, read) => {ok, IoDevice} | {error, Why}
• @spec io:read(IoDevice, Prompt) => {ok, Term} | {error,Why} | eof
• @spec file:close(IoDevice) => ok | {error, Why}
• 3. 一次读入一行
• 使用io:get_line(IoDevice,Prompt) => Line|eof
• 4. 将整个文件一次性读入,得到一个二进制数据
• file:read_file(File)
• 5. 打开文件,进行随机访问
• file:open(File,[read,binary,raw]).
• file:pread(IoDevice, Start, Len),从IoDevice中读取Start开始的Len个字节,文件从1开始,如果Len大于文件字节总数,返回全部内容
写文件的方式
• 1. 格式化写入
• @spec io:format(IoDevice, Format, Args) -> ok
• Format 写入的格式,例如
• ~n,~p,~w,~s
• 对于~s(格式化字符串),可以有更复杂的格式,例如
Format Result
io:format("|~10s|~n", ["abc"]) | abc|
io:format("|~-10s|~n", ["abc"]) |abc |
io:format("|~10.3.+s|~n",["abc"]) |+++++++abc|
io:format("|~10.10.+s|~n",["abc"]) |abc+++++++|
io:format("|~10.7.+s|~n",["abc"]) |+++abc++++|
• 2. 一次性写入整个文件
• file:write_file(File, IO)
• 3. 随机写入,注意,是覆盖原来的内容
1> {ok, S} = file:open("...", [raw,write,binary])
{ok, ...}
2> file:pwrite(S, 10, <<"new">>)
ok
3> file:close(S)
ok
目录操作
• file:list_dir(Dir).
• file:make_dir(Dir).
• file:delete_dir(Dir).删除非空目录
文件操作
• file:copy(File,Dest).
• file:delete(File).
读取文件信息
• file:read_file_info(File).
-record(file_info,
{size :: non_neg_integer(), % Size of file in bytes.
type :: 'device' | 'directory' | 'other' | 'regular' | 'symlink',
access :: 'read' | 'write' | 'read_write' | 'none',
atime :: date_time(), % The local time the file was last read:
% {{Year, Mon, Day}, {Hour, Min, Sec}}.
mtime :: date_time(), % The local time the file was last written.
ctime :: date_time(), % The interpretation of this time field
% is dependent on operating system.
% On Unix it is the last time the file or
% or the inode was changed. On Windows,
% it is the creation time.
mode :: integer(), % File permissions. On Windows,
% the owner permissions will be
% duplicated for group and user.
links :: non_neg_integer(), % Number of links to the file (1 if the
% filesystem doesn't support links).
major_device :: integer(), % Identifies the file system (Unix),
% or the drive number (A: = 0, B: = 1)
% (Windows).
%% The following are Unix specific.
%% They are set to zero on other operating systems.
minor_device, % Only valid for devices.
inode :: integer(), % Inode number for file.
uid :: integer(), % User id for owner (integer).
gid :: integer()}). % Group id for owner (integer).
一个文件查找的例子
-module(lib_find).
-export([files/3, files/5]).
-import(lists, [reverse/1]).
-include_lib("kernel/include/file.hrl" ).
%% Dir 要查找的目录
%% Re 正则表达式,例如*.mp3
%% Flag 是否要递归
files(Dir, Re, Flag) ->
Re1 = regexp:sh_to_awk(Re),
reverse(files(Dir, Re1, Flag, fun(File, Acc) ->[File|Acc] end, [])).
files(Dir, Reg, Recursive, Fun, Acc) ->
case file:list_dir(Dir) of
{ok, Files} -> find_files(Files, Dir, Reg, Recursive, Fun, Acc);
{error, _} -> Acc
end.
find_files([File|T], Dir, Reg, Recursive, Fun, Acc0) ->
FullName = filename:join([Dir,File]),
case file_type(FullName) of
regular ->
case regexp:match(FullName, Reg) of
{match, _, _} ->
Acc = Fun(FullName, Acc0),
find_files(T, Dir, Reg, Recursive, Fun, Acc);
_ ->
find_files(T, Dir, Reg, Recursive, Fun, Acc0)
end;
directory ->
case Recursive of
true ->
Acc1 = files(FullName, Reg, Recursive, Fun, Acc0),
find_files(T, Dir, Reg, Recursive, Fun, Acc1);
false ->
find_files(T, Dir, Reg, Recursive, Fun, Acc0)
end;
error ->
find_files(T, Dir, Reg, Recursive, Fun, Acc0)
end;
find_files([], _, _, _, _, A) ->
A.
file_type(File) ->
case file:read_file_info(File) of
{ok, Facts} ->
case Facts#file_info.type of
regular -> regular;
directory -> directory;
_ -> error
end;
_ ->
error
end.