コンテンツにスキップ

ファイルシステム

サンドボックス化されたファイルシステムボリューム内でファイルを読み取り、書き込み、管理。

ファイルシステム設定についてはファイルシステムを参照。

local fs = require("fs")

レジストリIDでファイルシステムボリュームを取得:

local vol, err = fs.get("app:storage")
if err then
return nil, err
end
local content = vol:readfile("/config.json")
パラメータ説明
namestringボリュームレジストリID

戻り値: FS, error

ボリュームは明示的な解放は不要。システムレベルで管理され、ファイルシステムがレジストリから切り離されると利用不可になる。

ファイル内容全体を読み取り:

local vol = fs.get("app:config")
local data, err = vol:readfile("/settings.json")
if err then
return nil, err
end
local config = json.decode(data)

大きなファイルにはopen()でストリーミングを使用:

local file = vol:open("/data/large.csv", "r")
while true do
local chunk = file:read(65536)
if not chunk or #chunk == 0 then break end
process(chunk)
end
file:close()

ファイルにデータを書き込み:

local vol = fs.get("app:data")
-- 上書き(デフォルト)
vol:writefile("/config.json", json.encode(config))
-- 追記
vol:writefile("/logs/app.log", message .. "\n", "a")
-- 排他的書き込み(存在する場合は失敗)
local ok, err = vol:writefile("/lock.pid", tostring(pid), "wx")
モード説明
"w"上書き(デフォルト)
"a"追記
"wx"排他的書き込み(ファイルが存在する場合は失敗)

ストリーミング書き込み:

local file = vol:open("/output/report.txt", "w")
file:write("Header\n")
file:write("Data: " .. value .. "\n")
file:sync()
file:close()
local vol = fs.get("app:data")
-- 存在確認
if vol:exists("/cache/results.json") then
return vol:readfile("/cache/results.json")
end
-- ディレクトリかどうかを確認
if vol:isdir(path) then
process_directory(path)
end
-- ファイル情報を取得
local info = vol:stat("/documents/report.pdf")
print(info.size, info.modified, info.type)

Statフィールド: namesizemodemodifiedis_dirtype

local vol = fs.get("app:data")
-- ディレクトリを作成
vol:mkdir("/uploads/" .. user_id)
-- ディレクトリ内容を一覧
for entry in vol:readdir("/documents") do
print(entry.name, entry.type)
end
-- ファイルまたは空のディレクトリを削除
vol:remove("/temp/file.txt")

Entryフィールド: nametype(“file”または”directory”)

ストリーミング用にvol:open()を使用する場合:

メソッド説明
read(size?)バイトを読み取り(デフォルト: 4096)
write(data)文字列データを書き込み
seek(whence, offset)位置を設定(“set”、“cur”、“end”)
stat()ファイル情報を取得(フィールドは vol:stat と同じ)
sync()ストレージにフラッシュ
close()ファイルハンドルを解放
scanner(split?)行/単語スキャナを作成

ファイルハンドルの使用が終わったら必ずclose()を呼び出すこと。

行単位の処理:

local file = vol:open("/data/users.csv", "r")
local scanner = file:scanner("lines")
scanner:scan() -- ヘッダーをスキップ
while scanner:scan() do
local line = scanner:text()
process(line)
end
file:close()

スプリットモード: "lines"(デフォルト)、"words""bytes""runes"

fs.type.FILE -- "file"
fs.type.DIR -- "directory"
fs.seek.SET -- 先頭から
fs.seek.CUR -- 現在位置から
fs.seek.END -- 末尾から
メソッド戻り値説明
readfile(path) / read_file(path)string, errorファイル全体を読み取り
writefile(path, data, mode?) / write_file(path, data, mode?)boolean, errorファイルを書き込み
exists(path)boolean, errorパスが存在するか確認
stat(path)table, errorファイル情報を取得
isdir(path)boolean, errorディレクトリか確認
mkdir(path)boolean, errorディレクトリを作成
remove(path)boolean, errorファイル/空のディレクトリを削除
readdir(path)iteratorディレクトリを一覧
open(path, mode)File, errorファイルハンドルを開く
chdir(path)boolean, error作業ディレクトリを変更
pwd()string, error作業ディレクトリを取得

ファイルシステムアクセスはセキュリティポリシー評価の対象。

アクションリソース説明
fs.getVolume IDファイルシステムボリュームを取得
条件種別再試行可能
パスが空errors.INVALIDno
無効なモードerrors.INVALIDno
ファイルがクローズ済みerrors.INVALIDno
パスが見つからないerrors.NOT_FOUNDno
パスが既に存在errors.ALREADY_EXISTSno
権限拒否errors.PERMISSION_DENIEDno

エラーの処理についてはエラー処理を参照。