如何通过TextWriter向JsonTextWriter写入字符串属性值
解决方案
我们可以通过实现自定义TextWriter适配器的方式,直接对接JsonTextWriter的写入流程,完全省略中间StringWriter实例和临时字符串生成步骤,大内容场景下的内存开销和性能提升会尤其明显。
1. 改造后的WriteContentToValue方法
public void WriteContentToValue(JsonTextWriter writer) { if (this.Content is JToken jToken) { jToken.WriteTo(writer); return; } // 无需中间StringWriter的替代逻辑 writer.WriteStartString(); using (var adapter = new JsonTextWriterStringAdapter(writer)) { WriteContentTo(adapter); } writer.WriteEndString(); }
2. 自定义TextWriter适配器实现
这个适配器会自动把WriteContentTo输出的所有内容做JSON字符串转义后直接写入目标JsonTextWriter,转义规则和Newtonsoft.Json原生规则完全一致,不会生成非法JSON:
using System; using System.IO; using System.Text; using Newtonsoft.Json; public class JsonTextWriterStringAdapter : TextWriter { private readonly JsonTextWriter _targetWriter; private static readonly char[] _quoteTrimChars = { '"' }; public JsonTextWriterStringAdapter(JsonTextWriter targetWriter) { _targetWriter = targetWriter ?? throw new ArgumentNullException(nameof(targetWriter)); } // 可根据你的实际输出编码调整,一般场景保持UTF8即可 public override Encoding Encoding => Encoding.UTF8; public override void Write(char value) { string escaped = JsonConvert.ToString(value.ToString()).Trim(_quoteTrimChars); _targetWriter.WriteRaw(escaped); } public override void Write(string value) { if (string.IsNullOrEmpty(value)) return; string escaped = JsonConvert.ToString(value).Trim(_quoteTrimChars); _targetWriter.WriteRaw(escaped); } public override void Write(char[] buffer, int index, int count) { if (buffer == null || count <= 0) return; string escaped = JsonConvert.ToString(new string(buffer, index, count)).Trim(_quoteTrimChars); _targetWriter.WriteRaw(escaped); } // 如果你的WriteContentTo使用异步写入,可按需重写对应WriteAsync系列方法 }
注意事项
- 该方案的输出结果与原有逻辑完全等价,不存在兼容性问题
- 如果追求极致性能,可通过反射调用Newtonsoft.Json内部的字符串转义方法跳过前后引号截取步骤,不过当前公开API实现已经可以满足绝大多数场景的性能需求
内容的提问来源于stack exchange,提问作者dgasaway
相关产品推荐
相关产品推荐

