为什么XmlWriter总是输出utf-16编码?

我有这种扩展方法

public static string SerializeObject(this T value) { var serializer = new XmlSerializer(typeof(T)); var settings = new XmlWriterSettings { Encoding = new UTF8Encoding(true), Indent = false, OmitXmlDeclaration = false, NewLineHandling = NewLineHandling.None }; using(var stringWriter = new StringWriter()) { using(var xmlWriter = XmlWriter.Create(stringWriter, settings)) { serializer.Serialize(xmlWriter, value); } return stringWriter.ToString(); } } 

但每当我调用它时,它的编码为utf-16指定,即 。 我究竟做错了什么?

字符串是UTF-16,因此写入StringWriter将始终使用UTF-16。 如果那不是您想要的,那么使用其他TextWriter派生类,使用您喜欢的编码。

据我所知,StringWriter类在序列化为字符串时将始终使用UTF 16编码。 您可以编写自己的覆盖类,接受不同的编码:

 public class StringWriterWithEncoding : StringWriter { private readonly Encoding _encoding; public StringWriterWithEncoding() { } public StringWriterWithEncoding(IFormatProvider formatProvider) : base(formatProvider) { } public StringWriterWithEncoding(StringBuilder sb) : base(sb) { } public StringWriterWithEncoding(StringBuilder sb, IFormatProvider formatProvider) : base(sb, formatProvider) { } public StringWriterWithEncoding(Encoding encoding) { _encoding = encoding; } public StringWriterWithEncoding(IFormatProvider formatProvider, Encoding encoding) : base(formatProvider) { _encoding = encoding; } public StringWriterWithEncoding(StringBuilder sb, Encoding encoding) : base(sb) { _encoding = encoding; } public StringWriterWithEncoding(StringBuilder sb, IFormatProvider formatProvider, Encoding encoding) : base(sb, formatProvider) { _encoding = encoding; } public override Encoding Encoding { get { return (null == _encoding) ? base.Encoding : _encoding; } } } 

所以你可以用它代替:

 using(var stringWriter = new StringWriterWithEncoding( Encoding.UTF8)) { ... } 

您应该从StringWriter派生一个具有覆盖编码属性的新类。

正如公认的答案所说, StringWriter默认为UTF-16(Unicode)设计。 如果你想通过最终得到一个UTF-8字符串来实现它,我有两种方法可以让你完成它:

解决方案#1(不是非常有效,不好的做法,但完成工作):将其转储到文本文件并重新读取,删除文件(可能只适用于小文件,如果你甚至想要这样做 – 只是想表明它可以完成!)

 public static string SerializeObject(this T value) { var serializer = new XmlSerializer(typeof(T)); var settings = new XmlWriterSettings { Encoding = new UTF8Encoding(true), Indent = false, OmitXmlDeclaration = false, NewLineHandling = NewLineHandling.None }; using(var xmlWriter = XmlWriter.Create("MyFile.xml", settings)) { serializer.Serialize(xmlWriter, value); } XmlDocument xml = new XmlDocument(); xml.Load("MyFile.xml"); byte[] bytes = Encoding.UTF8.GetBytes(xml.OuterXml); File.Delete("MyFile.xml"); return Encoding.UTF8.GetString(bytes); } 

解决方案#2(更好,更简单,更优雅的解决方案!):使用StringWriter ,就像拥有它一样,但使用其Encoding属性将其设置为UTF-8:

 public static string SerializeObject(this T value) { var serializer = new XmlSerializer(typeof(T)); var settings = new XmlWriterSettings { Encoding = new UTF8Encoding(true), Indent = false, OmitXmlDeclaration = false, NewLineHandling = NewLineHandling.None }; using(var stringWriter = new UTF8StringWriter()) { using(var xmlWriter = XmlWriter.Create(stringWriter, settings)) { serializer.Serialize(xmlWriter, value); } return stringWriter.ToString(); } } public class UTF8StringWriter : StringWriter { public override Encoding Encoding { get { return Encoding.UTF8; } } }