The IO module (CoreModules.IO) provides file input/output capabilities. Proper support requires a compatible IPlatformAccessor implementation.
The IO module is not available in Unity builds due to platform restrictions. It requires full file system access.
Standard Streams
SolarSharp provides access to standard input, output, and error streams:
io.stdin -- Standard input stream
io.stdout -- Standard output stream
io.stderr -- Standard error stream
File Operations
io.open(filename [, mode [, encoding]])
Opens a file and returns a file handle.
-- Read mode (default)
local file = io.open("data.txt", "r")
if file then
local content = file:read("*a")
file:close()
end
-- Write mode
local file = io.open("output.txt", "w")
if file then
file:write("Hello, World!\n")
file:close()
end
-- Append mode
local file = io.open("log.txt", "a")
if file then
file:write("Log entry\n")
file:close()
end
Modes:
"r" - Read (default)
"w" - Write (overwrites existing file)
"a" - Append
"r+" - Read and write
"w+" - Read and write (overwrites)
"a+" - Read and append
"b" - Binary mode (add to any mode, e.g., "rb")
"t" - Text mode (default)
Encoding:
nil - UTF-8 for text mode, binary for binary mode
"binary" - Binary encoding
- Any .NET encoding name (e.g.,
"utf-8", "utf-16", "ascii")
Returns: File handle on success, or nil plus error message on failure
local file, err = io.open("nonexistent.txt", "r")
if not file then
print("Error: " .. err)
end
io.close([file])
Closes a file handle.
local file = io.open("data.txt", "r")
io.close(file)
-- Or using file method
file:close()
-- Close default output file
io.close()
io.tmpfile()
Creates a temporary file.
local temp = io.tmpfile()
temp:write("temporary data")
temp:seek("set", 0) -- Rewind to beginning
local data = temp:read("*a")
temp:close()
Returns: File handle opened in write mode
io.type(obj)
Checks if an object is a file handle.
local file = io.open("test.txt", "r")
print(io.type(file)) -- "file"
file:close()
print(io.type(file)) -- "closed file"
print(io.type("string")) -- nil
Returns: "file", "closed file", or nil
Default Files
Sets or gets the default input file.
-- Get current default input
local current = io.input()
-- Set default input to a file
io.input("input.txt")
-- Or set using a file handle
local file = io.open("data.txt", "r")
io.input(file)
-- Now io.read() reads from the default input
local line = io.read()
io.output([file])
Sets or gets the default output file.
-- Redirect output to file
io.output("output.txt")
io.write("This goes to output.txt\n")
-- Restore stdout
io.output(io.stdout)
io.write("This goes to console\n")
Reading
io.read(…)
Reads from the default input file.
-- Read a line
local line = io.read()
-- Read a number
local num = io.read("*n")
-- Read entire file
local content = io.read("*a")
-- Read specific number of characters
local chars = io.read(10)
Formats:
"*n" - Read a number
"*a" - Read entire file
"*l" or "*L" - Read a line (default)
- number - Read that many characters
file:read(…)
Reads from a specific file handle.
local file = io.open("data.txt", "r")
-- Read line by line
for line in file:lines() do
print(line)
end
-- Read entire file
file:seek("set", 0) -- Rewind
local content = file:read("*a")
file:close()
io.lines(filename)
Iterates over lines in a file.
-- Read file line by line without explicit open/close
for line in io.lines("data.txt") do
print(line)
end
Returns: Iterator function that returns each line
Note: In SolarSharp, this reads all lines into memory first.
file:lines()
Iterates over lines in an open file.
local file = io.open("data.txt", "r")
for line in file:lines() do
print(line)
end
file:close()
Writing
io.write(…)
Writes to the default output file.
io.write("Hello", " ", "World", "\n")
io.write(string.format("Number: %d\n", 42))
Parameters: Multiple values to write (converted to strings)
file:write(…)
Writes to a specific file handle.
local file = io.open("output.txt", "w")
file:write("Line 1\n")
file:write("Line 2\n")
file:close()
io.flush()
Flushes the default output file.
io.write("Buffered data")
io.flush() -- Ensure it's written immediately
file:flush()
Flushes a specific file handle.
local file = io.open("log.txt", "a")
file:write("Important log entry\n")
file:flush() -- Ensure it's written to disk
File Handle Methods
File handles returned by io.open() have these methods:
file:read(…)
Reads from the file (see io.read for formats).
file:write(…)
Writes to the file.
file:close()
Closes the file.
file:flush()
Flushes buffered data to disk.
file:seek([whence [, offset]])
Sets or gets file position.
local file = io.open("data.txt", "r")
-- Get current position
local pos = file:seek()
-- Seek to beginning
file:seek("set", 0)
-- Seek relative to current position
file:seek("cur", 10)
-- Seek to end
file:seek("end", 0)
file:close()
Whence:
"set" - From beginning of file
"cur" - From current position
"end" - From end of file
Returns: New file position
file:lines()
Returns an iterator for reading lines.
Examples
Read Entire File
function readFile(filename)
local file = io.open(filename, "r")
if not file then
return nil, "Could not open file"
end
local content = file:read("*a")
file:close()
return content
end
local content, err = readFile("data.txt")
if content then
print(content)
else
print("Error: " .. err)
end
Write to File
function writeFile(filename, content)
local file = io.open(filename, "w")
if not file then
return false, "Could not open file"
end
file:write(content)
file:close()
return true
end
local ok, err = writeFile("output.txt", "Hello, World!\n")
if not ok then
print("Error: " .. err)
end
Append to File
function appendLog(filename, message)
local file = io.open(filename, "a")
if file then
file:write(os.date("%Y-%m-%d %H:%M:%S"), " - ", message, "\n")
file:close()
end
end
appendLog("app.log", "Application started")
Process File Line by Line
function processFile(filename)
local lineCount = 0
local wordCount = 0
for line in io.lines(filename) do
lineCount = lineCount + 1
for word in string.gmatch(line, "%S+") do
wordCount = wordCount + 1
end
end
return lineCount, wordCount
end
local lines, words = processFile("document.txt")
print(string.format("Lines: %d, Words: %d", lines, words))
Copy File
function copyFile(source, dest)
local input = io.open(source, "rb")
if not input then
return false, "Cannot open source file"
end
local output = io.open(dest, "wb")
if not output then
input:close()
return false, "Cannot create destination file"
end
local content = input:read("*a")
output:write(content)
input:close()
output:close()
return true
end
Read CSV File
function readCSV(filename)
local rows = {}
for line in io.lines(filename) do
local row = {}
for field in string.gmatch(line, '([^,]+)') do
table.insert(row, field)
end
table.insert(rows, row)
end
return rows
end
C# Configuration
using SolarSharp.Interpreter;
using SolarSharp.Interpreter.Modules;
// Enable IO module
var script = new Script(CoreModules.Preset_Default);
// Configure custom streams
script.Options.Stdin = myInputStream;
script.Options.Stdout = myOutputStream;
script.Options.Stderr = myErrorStream;
Error Handling
Most IO functions return nil plus an error message on failure:
local file, err = io.open("missing.txt", "r")
if not file then
print("Error: " .. err) -- "missing.txt: No such file or directory"
end
- Windows: Use
"rb" and "wb" for binary files to avoid newline translation
- Unity: IO module is not supported
- Sandboxing: Consider security implications when enabling file access
See Also