0Pricing
Lua Academy · レッスン

ファイルへの書き込みと追記

文字列をファイルに書き込み、既存の内容を上書きせずにデータを追記します。

「ファイルへの書き込みと追記」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。

f:write()の基本

f:write(...)は、1つ以上の文字列(または数値)をファイルに書き込みます。改行は自動的に追加されません。成功時はファイルハンドルを返すため、メソッドチェーンが可能です。失敗時は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のファイルI/Oはバッファリングされます。f:write()で書き込んだデータは、ディスクに到達する前にバッファに残る場合があります。f:flush()はファイルを閉じずに、バッファの内容をディスクへ強制的に書き込みます。別のプロセスからデータを参照できるようにする必要がある場合は、必ず事前に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形式にシリアライズするには、ヘッダー行を書き込み、続けてレコードごとに1行を書き込みます。その際、すべての値を文字列に変換し、カンマで結合します。

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)に書き込みます
  • アトミック書き込み: 一時ファイルに書き込んでから名前を変更します
  • 実運用では書き込みの戻り値を確認します

よくある質問

「ファイルへの書き込みと追記」レッスンは無料ですか?

はい。「ファイルへの書き込みと追記」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。

「ファイルへの書き込みと追記」で何を学びますか?

文字列をファイルに書き込み、既存の内容を上書きせずにデータを追記します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Lua Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「ファイルへの書き込みと追記」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLua Academyレッスンでコードを書いて実行できますか?

はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. io.openによるファイルのオープン
  2. ファイル内容の読み込み
  3. ファイルへの書き込みと追記
  4. ファイルのクローズとエラー処理
← Lua Academyに戻る