You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP C#硬重启致XML文件损坏,FileStream初始化抛异常求助

Fixing Corrupted XML Files After Hard Reboot in UWP C#

Hey there, let's work through this XML corruption issue you're hitting after a hard reboot in your UWP C# app. It's super frustrating when unexpected hardware resets break your data files, so let's break down the problem and fix it step by step.

First, the root cause: when your device hard-resets mid-write to the XML file, the file gets truncated or left with incomplete XML structure. This causes exceptions when you try to open it with FileStream or parse it later.

Step 1: Add Robust Error Handling for File Access

Instead of directly opening the file with FileStream, first validate the file's existence and basic integrity, and handle exceptions gracefully. Also, in UWP, it's better to use the StorageFile/StorageFolder APIs (designed for UWP's security model) instead of raw FileStream where possible.

Here's an improved version of your file check method with error handling:

using System.Xml;
using Windows.Storage;
using Windows.Storage.Search;

public async Task<bool> ValidateAndPrepareSettingsFile(string fileName)
{
    try
    {
        var musicLibrary = await KnownFolders.MusicLibrary.GetFolderAsync();
        var settingsFile = await musicLibrary.TryGetItemAsync(fileName) as StorageFile;

        // Case 1: File doesn't exist - create default
        if (settingsFile == null)
        {
            await CreateDefaultSettingsFile(musicLibrary, fileName);
            return true;
        }

        // Case 2: File is empty (definitely corrupted)
        var fileProps = await settingsFile.GetBasicPropertiesAsync();
        if (fileProps.Size == 0)
        {
            await RepairCorruptedFile(musicLibrary, fileName);
            return true;
        }

        // Case 3: Validate XML structure
        using (var stream = await settingsFile.OpenReadAsync())
        using (var xmlReader = XmlReader.Create(stream.AsStreamForRead(), new XmlReaderSettings { Async = true }))
        {
            try
            {
                // Attempt to read the entire XML document
                while (await xmlReader.ReadAsync()) { }
                return true;
            }
            catch (XmlException)
            {
                // XML is malformed - trigger repair
                await RepairCorruptedFile(musicLibrary, fileName);
                return true;
            }
        }
    }
    catch (Exception ex)
    {
        // Catch other errors (permission issues, etc.)
        System.Diagnostics.Debug.WriteLine($"File validation error: {ex.Message}");
        await RepairCorruptedFile(await KnownFolders.MusicLibrary.GetFolderAsync(), fileName);
        return false;
    }
}

Step 2: Implement Backup & Repair Logic

To recover from corrupted files, keep a backup of the last valid XML. Every time you successfully write to the main file, update the backup. If the main file is corrupted, fall back to the backup or create a default file.

private async Task CreateDefaultSettingsFile(StorageFolder folder, string fileName)
{
    // Create a fresh, valid XML file
    var newFile = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
    var defaultXmlContent = "<AppSettings><LastSessionValue>0</LastSessionValue></AppSettings>";
    await FileIO.WriteTextAsync(newFile, defaultXmlContent);

    // Create initial backup
    await newFile.CopyAsync(folder, $"{fileName}.bak", NameCollisionOption.ReplaceExisting);
}

private async Task RepairCorruptedFile(StorageFolder folder, string fileName)
{
    var backupFile = await folder.TryGetItemAsync($"{fileName}.bak") as StorageFile;

    if (backupFile != null)
    {
        // Replace corrupted file with backup
        await backupFile.CopyAsync(folder, fileName, NameCollisionOption.ReplaceExisting);
    }
    else
    {
        // No backup exists - create default file
        await CreateDefaultSettingsFile(folder, fileName);
    }
}

Step 3: Prevent Corruption with Atomic Writes

The best way to avoid this issue long-term is to use atomic writes. Instead of overwriting the original file directly, write to a temporary file first. Only when the write is successful, replace the original file with the temp one. This ensures the original file stays intact if a reboot happens mid-write.

public async Task SaveSettingsToXml(string fileName, string xmlContent)
{
    var musicLibrary = await KnownFolders.MusicLibrary.GetFolderAsync();
    var tempFile = await musicLibrary.CreateFileAsync($"{fileName}.tmp", CreationCollisionOption.ReplaceExisting);

    // Write to temp file first
    await FileIO.WriteTextAsync(tempFile, xmlContent);

    // Get the original file (or create if it doesn't exist)
    var originalFile = await musicLibrary.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);

    // Replace original with temp (atomic operation)
    await tempFile.MoveAndReplaceAsync(originalFile);

    // Update backup
    await originalFile.CopyAsync(musicLibrary, $"{fileName}.bak", NameCollisionOption.ReplaceExisting);
}

Bonus: Consider Alternate Storage Options

If XML continues to cause issues, consider using more robust storage options built into UWP:

  • ApplicationData.LocalSettings: Perfect for small key-value pairs (no XML needed, built-in serialization)
  • SQLite: Great for larger, structured data (more resilient to corruption than plain text files)

内容的提问来源于stack exchange,提问作者Jeyson Mg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:41:34