Filesystem
Read, write, and manage files within sandboxed filesystem volumes.
For filesystem configuration, see Filesystem.
Loading
local fs = require("fs")
Acquiring a Volume
Get a filesystem volume by registry ID:
local vol, err = fs.get("app:storage")
if err then
return nil, err
end
local content = vol:readfile("/config.json")
| Parameter | Type | Description |
|---|---|---|
name |
string | Volume registry ID |
Returns: FS, error
Reading Files
Read entire file contents:
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)
For large files, use streaming with 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()
Writing Files
Write data to a file:
local vol = fs.get("app:data")
-- Overwrite (default)
vol:writefile("/config.json", json.encode(config))
-- Append
vol:writefile("/logs/app.log", message .. "\n", "a")
-- Exclusive write (fails if exists)
local ok, err = vol:writefile("/lock.pid", tostring(pid), "wx")
| Mode | Description |
|---|---|
"w" |
Overwrite (default) |
"a" |
Append |
"wx" |
Exclusive write (fails if file exists) |
For streaming writes:
local file = vol:open("/output/report.txt", "w")
file:write("Header\n")
file:write("Data: " .. value .. "\n")
file:sync()
file:close()
Checking Paths
local vol = fs.get("app:data")
-- Check existence
if vol:exists("/cache/results.json") then
return vol:readfile("/cache/results.json")
end
-- Check if directory
if vol:isdir(path) then
process_directory(path)
end
-- Get file info
local info = vol:stat("/documents/report.pdf")
print(info.size, info.modified, info.type)
Stat fields: name, size, mode, modified, is_dir, type
Directory Operations
local vol = fs.get("app:data")
-- Create directory
vol:mkdir("/uploads/" .. user_id)
-- List directory contents
for entry in vol:readdir("/documents") do
print(entry.name, entry.type)
end
-- Remove file or empty directory
vol:remove("/temp/file.txt")
Entry fields: name, type ("file" or "directory")
File Handle Methods
When using vol:open() for streaming:
| Method | Description |
|---|---|
read(size?) |
Read bytes (default: 4096) |
write(data) |
Write string data |
seek(whence, offset) |
Set position ("set", "cur", "end") |
sync() |
Flush to storage |
close() |
Release file handle |
scanner(split?) |
Create line/word scanner |
Always call close() when done with a file handle.
Scanner
For line-by-line processing:
local file = vol:open("/data/users.csv", "r")
local scanner = file:scanner("lines")
scanner:scan() -- skip header
while scanner:scan() do
local line = scanner:text()
process(line)
end
file:close()
Split modes: "lines" (default), "words", "bytes", "runes"
Constants
fs.type.FILE -- "file"
fs.type.DIR -- "directory"
fs.seek.SET -- from start
fs.seek.CUR -- from current
fs.seek.END -- from end
FS Methods
| Method | Returns | Description |
|---|---|---|
readfile(path) |
string, error |
Read entire file |
writefile(path, data, mode?) |
boolean, error |
Write file |
exists(path) |
boolean, error |
Check if path exists |
stat(path) |
table, error |
Get file info |
isdir(path) |
boolean, error |
Check if directory |
mkdir(path) |
boolean, error |
Create directory |
remove(path) |
boolean, error |
Remove file/empty dir |
readdir(path) |
iterator |
List directory |
open(path, mode) |
File, error |
Open file handle |
chdir(path) |
boolean, error |
Change working dir |
pwd() |
string |
Get working dir |
Permissions
Filesystem access is subject to security policy evaluation.
| Action | Resource | Description |
|---|---|---|
fs.get |
Volume ID | Acquire filesystem volume |
Errors
| Condition | Kind | Retryable |
|---|---|---|
| Empty path | errors.INVALID |
no |
| Invalid mode | errors.INVALID |
no |
| File is closed | errors.INVALID |
no |
| Path not found | errors.NOT_FOUND |
no |
| Path already exists | errors.ALREADY_EXISTS |
no |
| Permission denied | errors.PERMISSION_DENIED |
no |
See Error Handling for working with errors.