Skip to main content
The file system functions allow you to read from and write to files in the server’s game directory. All file operations are restricted to the fs_homepath directory for security.

Opening Files

fsOpen

Opens a file in the current game directory and returns a file handle.
fileHandle = fsOpen(filename, mode)
filename
string
required
The name of the file to open (relative to the game directory)
mode
string
required
The file access mode: "read", "write", or "append"
fileHandle
int
Returns a file handle (greater than 0) on success, or 0 on failure
Files must be closed after use with fsClose() to prevent resource leaks.
fh = fsOpen("config.txt", "read");
if (fh) {
    line = fsReadLine(fh);
    iPrintLn("First line: " + line);
    fsClose(fh);
}

Reading Files

fsReadLine

Reads a single line from an opened file.
line = fsReadLine(fileHandle)
fileHandle
int
required
The file handle returned by fsOpen()
line
string | undefined
Returns the line as a string (without the trailing \n), or undefined if at the end of the file or an error occurs
Example: Reading all
fh = fsOpen("data.txt", "read");
if (fh) {
    for (;;) {
        line = fsReadLine(fh);
        if (!isDefined(line))
            break;
        
        iPrintLn(line);
    }
    fsClose(fh);
}

Writing Files

fsWriteLine

Writes a line to an opened file. Automatically appends a newline character.
success = fsWriteLine(fileHandle, data)
fileHandle
int
required
The file handle returned by fsOpen()
data
string
required
The string data to write to the file
success
bool
Returns true on success, false on failure
Example: Writing multiple
fh = fsOpen("players.txt", "write");
if (fh) {
    players = getEntArray("player", "classname");
    for (i = 0; i < players.size; i++) {
        fsWriteLine(fh, players[i].name);
    }
    fsClose(fh);
}

Managing Files

fsClose

Closes an opened file. Always call this when done with a file.
fsClose(fileHandle)
fileHandle
int
required
The file handle to close
Failing to close files can lead to resource exhaustion. Always close files in error handling paths as well.

fsRemove

Deletes a file from the file system.
success = fsRemove(filename)
filename
string
required
The name of the file to delete
success
bool
Returns true if the file was deleted successfully, false otherwise
You cannot delete a file that is currently open. The function will return false and produce an error.
Example: Deleting old logs
if (testFile("old_log.txt")) {
    success = fsRemove("old_log.txt");
    if (success)
        iPrintLn("Old log deleted");
}

testFile

Checks if a file exists in the file system.
exists = testFile(filename)
filename
string
required
The name of the file to check
exists
bool
Returns true if the file exists, false otherwise
Example: Checking before reading
if (testFile("config.cfg")) {
    fh = fsOpen("config.cfg", "read");
    // ... read config
    fsClose(fh);
} else {
    iPrintLn("Config file not found");
}

Best Practices

Always Close Files

Use fsClose() immediately after you’re done with a file to prevent resource leaks.

Check File Handles

Always verify that fsOpen() returned a valid handle before attempting to read or write.

Use testFile

Check if a file exists before attempting to open it for reading.

Error Handling

Handle undefined returns from fsReadLine() to detect end-of-file conditions.

Complete Example

Example: Player statistics system
savePlayerStats(player) {
    filename = "stats/" + player getGuid() + ".txt";
    
    fh = fsOpen(filename, "write");
    if (!fh) {
        iPrintLn("Failed to save stats for " + player.name);
        return false;
    }
    
    fsWriteLine(fh, "name:" + player.name);
    fsWriteLine(fh, "kills:" + player.kills);
    fsWriteLine(fh, "deaths:" + player.deaths);
    fsWriteLine(fh, "score:" + player.score);
    
    fsClose(fh);
    return true;
}

loadPlayerStats(player) {
    filename = "stats/" + player getGuid() + ".txt";
    
    if (!testFile(filename))
        return false;
    
    fh = fsOpen(filename, "read");
    if (!fh)
        return false;
    
    for (;;) {
        line = fsReadLine(fh);
        if (!isDefined(line))
            break;
        
        tokens = strTok(line, ":");
        if (tokens.size != 2)
            continue;
        
        key = tokens[0];
        value = tokens[1];
        
        switch (key) {
            case "kills":
                player.kills = int(value);
                break;
            case "deaths":
                player.deaths = int(value);
                break;
            case "score":
                player.score = int(value);
                break;
        }
    }
    
    fsClose(fh);
    return true;
}

Build docs developers (and LLMs) love