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

Json字符串解析时出现意外字符,对象序列化存文件后反序列化失败如何解决

问题原因
  • 你使用的Encoding.UTF8实例默认会在UTF8编码内容开头插入3字节的BOM(字节顺序标记),读取字节数组直接转字符串时,BOM无法被正常识别为有效文本,就会显示为开头的问号,破坏了JSON的结构导致反序列化失败。
  • 写入流时未正确重置流指针、资源未正确释放也可能导致写入的内容不完整。
修复方案

方案1:修改写入逻辑(推荐,从根源避免BOM生成)

使用不带BOM的UTF8编码实例,同时用using自动管理资源:

var content = JsonConvert.SerializeObject(data);
using var output = new MemoryStream();
// 传入false参数表示不生成BOM头
using var writer = new StreamWriter(output, new UTF8Encoding(false));
writer.Write(content);
writer.Flush();
// 将流指针重置到开头再写入到目标文件
output.Position = 0;
// 这里补充你写入到指定文件的逻辑,比如output.CopyTo(文件流)

方案2:修改读取逻辑(兼容已生成的带BOM的文件)

不要手动把字节数组转字符串,用StreamReader自动识别处理BOM:

Stream filestream;
// filestream为已打开的对应文件流
using var reader = new StreamReader(filestream, Encoding.UTF8);
var data = reader.ReadToEnd();
var result = JsonConvert.DeserializeObject<T>(data);

如果必须保留现有字节数组读取逻辑,也可以手动去掉BOM头再转字符串:

byte[] buffer = new byte[4096];
using(MemoryStream ms = new MemoryStream()){
    int read;
    while((read = filestream.Read(buffer, 0, buffer.Length)) > 0){
        ms.Write(buffer, 0, read);
    }
    byte[] allBytes = ms.ToArray();
    // 检测并跳过BOM头
    int skip = 0;
    if (allBytes.Length >=3 && allBytes[0] == 0xEF && allBytes[1] == 0xBB && allBytes[2] == 0xBF)
    {
        skip = 3;
    }
    var data = Encoding.UTF8.GetString(allBytes, skip, allBytes.Length - skip);
    JsonConvert.DeserializeObject<T>(data);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 02:24:04