Erlang 从零 · 第 19 课(展开目录)
01 · 先打开 erl02 · 先认常见 term03 · 分清两种文字04 · 变量只接一次05 · 拆开一列,再筛一次06 · 把文字安全变成整数07 · 用 case 选一条路08 · 让函数继续走09 · 把代码放进模块10 · 条件必须说真话11 · 一层一层取数据12 · 文字先说清编码13 · 让函数子句排好队14 · 带着累加器往前走15 · 先看值,再选路16 · 给模块立规矩17 · 让 rebar3 管项目18 · 让结果有固定形状19 · 把磁盘当成会失败的邻居20 · 把函数交给 list21 · record 留在院里22 · 先写模块之间的约定23 · 把 term 形状写出来24 · 小测试与整段路25 · 把应用磨成命令26 · 先把小项目圈住27 · 把真实文件洗干净28 · 公开入口越少越稳29 · 把约定留在源码旁30 · 打包,也留下线索31 · 按最初任务交卷
ERLANG · 进阶 · LESSON 1935 分钟

把磁盘当成会失败的邻居

用 `file` 读写 binary,用 `io` 控制输出,不混淆两种边界。

01 · 先看完整例子

读写一个临时名单

filelib:ensure_dir/1 会创建 Path 的父目录。

Erlang
Path = filename:join(
  filename:basedir(user_cache, "beam_path"),
  "names.txt"
),
ok = filelib:ensure_dir(Path),

%% 只写当前用户缓存目录中的指定文件
ok = file:write_file(Path, <<"A-Qing
Xiao-Man
">>),
{ok, Text} = file:read_file(Path),

%% 去掉末尾空项
binary:split(Text, <<"
">>, [global, trim_all]).
先对照结果
  • 得到 [<<"A-Qing">>,<<"Xiao-Man">>]。
02 · 回头拆代码

从第一行往下读

  1. filename 模块按当前系统规则拼接路径。
  2. 写入与读取都显式匹配成功结果。
  3. 读回原始 binary 后,解析步骤单独进行。
03 · 认清新符号

符号不是暗号

file:write_file/2

把 iodata 写入指定路径。

file:read_file/1

把整个文件读为 binary。

io:format/2

按格式向标准输出写内容。

04 · 代码里的概念

把名字和意思对上

01

I/O 边界

程序与文件、终端等外部世界交接的位置。

02

I/O device

io 模块读写的设备,如标准输出或打开的文件。

05 · 再说清楚

这些写法为什么有用

磁盘文件可能不存在、无权限或写到一半失败。file 模块用结果 tuple 把问题交回来。

文件内容优先按 binary 读取,编码约定由项目明确。io 模块负责设备输出,不替代文件解析。

练习只写系统临时目录下指定文件,不碰自己的资料。

06 · 自己改一次

合上答案,动手

写入 <<"8\n9\n">>,再检查返回值。

练习起点
Path = filename:join("/tmp", "scores.txt"),
____ = file:write_file(Path, ____).

目标结果: 写入成功时整段得到 ok。

卡住了,再看提示

第一空是 ok,第二空是 binary。

运行过以后,再看一种答案
一种答案
Path = filename:join("/tmp", "scores.txt"),
%% 正式项目可改用 filename:basedir/2
ok = file:write_file(Path, <<"8
9
">>).
想一想:`file:read_file/1` 找不到文件时会返回什么形状?

通常返回 {error, enoent};调用者应处理 error tuple,而不是只写成功匹配。

带走

记住三句

  1. 1

    路径交给 filename 模块。

  2. 2

    文件操作始终可能失败。

  3. 3

    读取、解析与显示是三个不同步骤。

本课结束代码也跑过一次,就把这一课收好。