Course contentsShow
← Unity Game Development
Lesson 747 of 82811. Performance and Data PersistenceFree lesson

Implementing Robust Error Handling for File I/O

Develop resilient code patterns to manage file access exceptions and prevent data corruption during the reading and writing of save files.

In this lesson, you will learn how to wrap your file operations in resilient C# structures to prevent data corruption and unexpected crashes during save-game processes.

When writing or reading files in Unity, things can go wrong unexpectedly: the disk might be full, the player might lose permissions, or the system might interrupt the process mid-write. Simply calling File.WriteAllText is risky because if an error occurs halfway through, you could end up with a truncated, corrupted file, effectively deleting the player's progress.

The Atomic Write Pattern

To achieve robustness, we use a "Write-Rename" pattern. Instead of writing directly to the target save file, we write to a temporary file first. Only if the operation completes without exception do we swap the temporary file into the actual save location.

public void SaveGame(string data, string path)
{
    string tempPath = path + ".tmp";
    try
    {
        // 1. Write to temporary file to avoid corrupting the real file
        System.IO.File.WriteAllText(tempPath, data);

        // 2. If successful, replace the real file with the temp file
        if (System.IO.File.Exists(path)) System.IO.File.Delete(path);
        System.IO.File.Move(tempPath, path);
    }
    catch (System.Exception e)
    {
        Debug.LogError($"Failed to save game: {e.Message}");
        // Optional: Clean up temp file
        if (System.IO.File.Exists(tempPath)) System.IO.File.Delete(tempPath);
    }
}

Why this is robust

  • Exception Scoping: By wrapping the IO logic in try-catch blocks, your game remains responsive even if the hardware fails to commit the write.
  • Atomic Operations: The File.Move command is typically handled by the OS as a near-instantaneous atomic operation. The player's old save file remains untouched until the new data is fully verified and ready on disk.
  • Resource Cleanup: We explicitly handle potential leftover .tmp files in the catch block to ensure we aren't cluttering the user's storage if an operation fails.

Key Takeaway: Never overwrite your primary save file directly; always write to a temporary file and use a move operation to ensure data integrity through exception handling.