104 lines
2.9 KiB
C#

/*
* @Author: 白哉
* @Description:
* @Date: 2026年03月03日 星期二 14:03:22
* @Modify:
*/
using System;
using System.IO;
using Logic.CrashSight;
namespace TH1_Logic.Tools
{
public class FileTools
{
public static T TryDeserializeFile<T>(string path) where T : class
{
if (!File.Exists(path)) return null;
try
{
byte[] bytes = File.ReadAllBytes(path);
if (bytes.Length == 0)
{
LogSystem.LogError($"文件为空: {path}");
return null;
}
var data = TH1Serialization.Deserialize<T>(bytes);
if (data == null)
{
LogSystem.LogError($"反序列化结果无效: {path}");
return null;
}
return data;
}
catch (Exception e)
{
LogSystem.LogError($"读取文件失败: {path} | 错误: {e.Message}");
return null;
}
}
// 安全写入文件:先写临时文件,再备份旧文件,最后替换
public static bool SafeWriteFile(string path, byte[] data)
{
string tempPath = path + ".tmp";
string backupPath = path + ".bak";
try
{
// 确保目录存在
string dir = Path.GetDirectoryName(path);
if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
// 1. 写入临时文件
File.WriteAllBytes(tempPath, data);
// 2. 验证临时文件完整性(回读校验)
byte[] verification = File.ReadAllBytes(tempPath);
if (verification.Length != data.Length)
{
throw new IOException($"写入验证失败: 期望 {data.Length} 字节, 实际 {verification.Length} 字节");
}
// 3. 备份旧文件
if (File.Exists(path))
{
if (File.Exists(backupPath)) File.Delete(backupPath);
File.Copy(path, backupPath);
}
// 4. 替换原文件
if (File.Exists(path)) File.Delete(path);
File.Move(tempPath, path);
}
catch (Exception e)
{
LogSystem.LogError($"安全写入失败: {e.Message}");
// 清理临时文件
try
{
if (File.Exists(tempPath)) File.Delete(tempPath);
}
catch
{
// ignored
}
return false;
}
return true;
}
}
}