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
相关产品推荐
相关产品推荐

