使用BinaryReader解析Satisfactory游戏存档文件时返回字符串缺失前三个字符的问题求助
BinaryReader读取Satisfactory存档文件时丢失前三个字符
我编写了一段用于读取Satisfactory游戏存档文件的代码,读取后返回的字符串内容是正确的,但总是缺失前三个字符。我已经尝试了BinaryReader的不同方法和多种文件读取方式,还是没能解决这个问题。以下是我的代码实现:
using System.Diagnostics; using System.IO; using System.Security.Cryptography.X509Certificates; using System.Text; namespace SatisfactorySaveParser { public class FSaveHeader { public int SaveHeaderVersion; public int SaveVersion; public int BuildVersion; public string MapName; public string MapOptions; public string SessionName; public int PlayedSeconds; public long SaveTimeStamp; public byte SessionVisibility; public int UnrealEngineVersion; public string ModMetadata; public int ModFlags; public string SaveIdentifier; public void Parse(FileStream stream, string filename) { BinaryReader reader = new BinaryReader(stream, Encoding.UTF8); int Length = filename.Length; SaveHeaderVersion = reader.ReadInt32(); SaveVersion = reader.ReadInt32(); BuildVersion = reader.ReadInt32(); MapName = reader.ReadString(); MapOptions = reader.ReadString(); SessionName = reader.ReadString(); ModFlags = reader.ReadInt32(); PlayedSeconds = reader.ReadInt32(); SaveTimeStamp = reader.ReadInt32(); SessionVisibility = reader.ReadByte(); UnrealEngineVersion = reader.ReadInt32(); ModMetadata = reader.ReadString(); ModFlags = reader.ReadInt32(); SaveIdentifier = reader.ReadString(); } } }
看起来你的问题核心出在对Satisfactory存档格式的细节遗漏上,结合代码里的几个明显错误,我来帮你拆解修复:
1. 最关键的问题:存档开头的魔法数
Satisfactory的存档文件开头固定有3个字节的魔法数:'S','A','V'(对应ASCII码0x53、0x41、0x56)。你的代码直接跳过这三个字节就开始读取Int32,导致后续所有数据的读取位置都偏移了3个字节——这就是字符串内容正确但缺失前三个字符的原因,你把魔法数当成了后续字符串数据的一部分,自然会截断开头内容。
2. 代码里的其他错位问题
- 重复读取ModFlags:代码里连续两次执行
ModFlags = reader.ReadInt32();,会直接导致后续所有读取操作整体错位。 - SaveTimeStamp类型不匹配:你用
ReadInt32()读取long类型变量,会造成数据截断,应该改用ReadInt64()。 - 读取顺序错误:原代码在
SessionName之后先读取了ModFlags,但根据Satisfactory的存档结构,这里应该先读取PlayedSeconds,顺序错误同样会引发数据错位。 - 无效变量:定义的
Length = filename.Length;完全没有被使用,可以直接删除。
修正后的代码
using System.IO; using System.Text; namespace SatisfactorySaveParser { public class FSaveHeader { public int SaveHeaderVersion; public int SaveVersion; public int BuildVersion; public string MapName; public string MapOptions; public string SessionName; public int PlayedSeconds; public long SaveTimeStamp; public byte SessionVisibility; public int UnrealEngineVersion; public string ModMetadata; public int ModFlags; public string SaveIdentifier; public void Parse(FileStream stream) { BinaryReader reader = new BinaryReader(stream, Encoding.UTF8); // 读取并验证存档开头的魔法数 byte[] magicBytes = reader.ReadBytes(3); if (magicBytes[0] != 'S' || magicBytes[1] != 'A' || magicBytes[2] != 'V') { throw new InvalidDataException("这不是有效的Satisfactory存档文件"); } // 按照正确的顺序读取存档头数据 SaveHeaderVersion = reader.ReadInt32(); SaveVersion = reader.ReadInt32(); BuildVersion = reader.ReadInt32(); MapName = reader.ReadString(); MapOptions = reader.ReadString(); SessionName = reader.ReadString(); PlayedSeconds = reader.ReadInt32(); SaveTimeStamp = reader.ReadInt64(); SessionVisibility = reader.ReadByte(); UnrealEngineVersion = reader.ReadInt32(); ModMetadata = reader.ReadString(); ModFlags = reader.ReadInt32(); SaveIdentifier = reader.ReadString(); } } }
另外补充一点:Unreal Engine的FString格式和.NET BinaryReader.ReadString()的规则是匹配的(前缀为int32类型的长度,后跟UTF-8字节),所以只要读取顺序和格式匹配,就可以正常读取字符串内容。
内容的提问来源于stack exchange,提问作者Joelminer
相关产品推荐
相关产品推荐

