0Pricing
Lua Academy · 课时

写入和追加文件内容

将字符串写入文件,并在不覆盖原有内容的情况下追加数据。

写入和追加文件内容 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

f:write() 基础

f:write(...) 将一个或多个字符串(或数字)写入文件。它不会自动添加换行符。成功时返回文件句柄(因此可以链式调用),失败时返回 nil, errMessage, errCode。

local f = io.open("output.txt", "w")
if f then
  f:write("Hello, ")
  f:write("World")
  f:write("!\n")
  f:write("Line 2\n")
  f:close()
end

写入多个值

f:write() 接受多个参数,并按顺序依次写入。值必须是字符串或数字——传入其他类型会引发错误。请使用 tostring() 转换布尔值、表等类型。

local f = io.open("log.txt", "w")
f:write("Name: ", "Alice", "\n")
f:write("Age: ", 30, "\n")
f:write("Score: ", string.format("%.1f", 95.5), "\n")
f:close()

格式化写入

将 string.format 与 f:write 结合使用,可以精确控制输出。这种模式常用于生成报告、日志文件和数据导出,并满足特定的格式要求。

local data = {
  {name="Alice", score=95, grade="A"},
  {name="Bob",   score=87, grade="B"},
}

local f = io.open("report.txt", "w")
f:write(string.format("%-12s  %5s  %s\n","Name","Score","Grade"))
f:write(string.rep("-",25) .. "\n")
for _, r in ipairs(data) do
  f:write(string.format("%-12s  %5d  %s\n",r.name,r.score,r.grade))
end
f:close()

追加模式

"a" 模式始终在文件末尾写入。读取时的文件位置位于开头,但写入时始终转到末尾。它适用于日志、审计记录,以及任何需要添加内容而不擦除原有内容的文件。

local function appendLog(msg)
  local f = io.open("app.log", "a")
  if f then
    local ts = os.date("%Y-%m-%d %H:%M:%S")
    f:write(string.format("[%s] %s\n", ts, msg))
    f:close()
  end
end

appendLog("Server started")
appendLog("User logged in: Alice")
appendLog("Request processed")

f:flush() 与缓冲

Lua 中的文件输入输出采用缓冲机制。使用 f:write() 写入的数据可能会先停留在缓冲区中,之后才到达磁盘。f:flush() 会强制将缓冲区内容写入磁盘,但不会关闭文件。当您需要让另一个进程看到数据时,请务必先刷新缓冲区。

local f = io.open("stream.txt", "w")
for i = 1, 5 do
  f:write("Line " .. i .. "\n")
  f:flush()   -- ensure each line is on disk
  -- simulate work
end
f:close()

写入二进制数据

在二进制写入模式("wb")下,使用 string.char() 写入原始字节。这是创建二进制文件格式、图像或协议消息的方式。对于结构化二进制数据,请使用 string.pack(Lua 5.3 及更高版本)。

local f = io.open("bytes.bin", "wb")
if f then
  -- Write raw bytes
  f:write(string.char(0xFF, 0x00, 0xAB, 0xCD))
  -- Write a 4-byte little-endian integer (Lua 5.3+)
  f:write(string.pack("<I4", 12345))
  f:close()
  print("Written binary file")
end

io.write 与 f:write

io.write() 写入当前默认输出(最初为 stdout)。f:write() 写入指定的文件句柄。与 print() 不同,这两个函数都不会添加换行符或制表符分隔符,因此您可以完全控制输出格式。

-- io.write to stdout
io.write("Enter name: ")
-- (would read input here)

-- f:write to file
local f = io.open("out.txt", "w")
f:write("No auto newline")
f:write(" appended directly")
f:write("\n")  -- explicit newline
f:close()

-- print adds tabs and newline automatically
print("a", "b", "c")   -- a  b  c (tab-separated)

原子写入模式

为了确保安全性,请先写入临时文件,然后重命名该文件。这样可以避免输出文件处于部分写入状态。如果进程在写入过程中崩溃,原文件不会受到影响。

local function atomicWrite(path, content)
  local tmp = path .. ".tmp"
  local f, err = io.open(tmp, "w")
  if not f then return nil, err end
  f:write(content)
  f:close()
  -- os.rename is atomic on most filesystems
  local ok, err2 = os.rename(tmp, path)
  if not ok then
    os.remove(tmp)
    return nil, err2
  end
  return true
end

将表写入 CSV

将记录表序列化为 CSV 格式:先写入标题行,然后为每条记录写入一行,将所有值转换为字符串,并使用逗号连接。

local function writeCSV(path, headers, rows)
  local f = io.open(path, "w")
  if not f then return end
  f:write(table.concat(headers, ",") .. "\n")
  for _, row in ipairs(rows) do
    local fields = {}
    for _, h in ipairs(headers) do
      fields[#fields+1] = tostring(row[h] or "")
    end
    f:write(table.concat(fields, ",") .. "\n")
  end
  f:close()
end

writeCSV("data.csv",
  {"name","age","score"},
  {{name="Alice",age=30,score=95},{name="Bob",age=25,score=87}}
)

f:write() 的返回值

f:write() 成功时返回文件句柄,因此可以进行方法链式调用。失败时返回 nil、错误信息和错误代码。在生产代码中始终检查错误,尤其是在存储空间有限的系统上执行写入操作时。

local f = io.open("out.txt", "w")

-- Chaining writes
local ok, err = f:write("line1\n"):write("line2\n"):write("line3\n")
if not ok then
  print("Write failed:", err)
else
  print("All writes succeeded")
end
f:close()

快速检查

io.open 中的 "w" 和 "a" 模式有什么区别?

回顾:写入文件

总结:

  • f:write(...) —— 写入字符串或数字;不会自动换行
  • "w" 会截断文件,"a" 会追加内容
  • f:flush() 强制将缓冲区写入磁盘
  • io.write() 写入默认输出(stdout)
  • 原子写入:先写入临时文件,再重命名
  • 在生产环境中检查写入操作的返回值

常见问题解答

「写入和追加文件内容」课时是免费的吗?

是的 — 「写入和追加文件内容」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「写入和追加文件内容」这节课中我会学到什么?

将字符串写入文件,并在不覆盖原有内容的情况下追加数据。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「写入和追加文件内容」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 io.open 打开文件
  2. 读取文件内容
  3. 写入和追加文件内容
  4. 关闭文件和错误处理
← 返回 Lua Academy