XmlSerializer.Serialize 缺少 BOM

XmlSerializer.Serialize BOM missing

我正在使用此代码存储我的 class:

FileStream stream = new FileStream(myPath, FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(myClass));
serializer.Serialize(stream, myClass);
stream.Close();

这写了一个我可以用 XmlSerializer.Deserialize 阅读的文件。但是,生成的文件不是正确的文本文件。 XmlSerializer.Serialize 不存储 BOM,但仍插入多字节字符。因此它被隐含地声明为 ANSI 文件(因为我们期望 XML 文件是文本文件,而没有 BOM 的文本文件被 Windows 视为 ANSI),在某些情况下将 ö 显示为 ö编辑。

这是已知错误吗?或者我缺少的一些设置?

这是生成的文件的开头:

<?xml version="1.0"?>
<SvnProjects xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

文件中的第一个字节是十六进制 3C,即 <

有无 BOM 不是 "proper text file" 的定义。事实上,我想说现在最典型的格式是没有 BOM 的 UTF-8;我不认为我 曾经 见过有人在实际系统中实际使用 UTF-8 BOM!但是:如果您想要 BOM,那很好:只需将正确的 Encoding 传入;如果你想要带 BOM 的 UTF-8:

using (var writer = XmlWriter.Create(myPath, s_settings))
{
    XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
    serializer.Serialize(writer, obj);
}

与:

static readonly XmlWriterSettings s_settings =
    new XmlWriterSettings { Encoding = new UTF8Encoding(true) };

结果是一个以 EF-BB-BF、UTF-8 BOM 开头的文件。

如果您想要不同的编码,只需将new UTF8Encoding替换为您想要的任何内容,记得启用BOM。

(注意:静态 Encoding.UTF8 实例启用了 BOM,但是如果您特别打算使用 BOM,IMO 最好在这里非常明确,就像您应该非常明确地说明什么 Encoding 你打算使用)


编辑:这里的主要区别在于 Serialize(Stream, object) 最终使用:

XmlTextWriter xmlWriter = new XmlTextWriter(stream, encoding: null) {
    Formatting = Formatting.Indented,
    Indentation = 2
};

然后最终使用:

public StreamWriter(Stream stream) : this(stream,
    encoding: UTF8NoBOM, // <==== THIS IS THE PROBLEM
    bufferSize: 1024, leaveOpen: false)
{
}

所以:如果您使用 API.

,则默认为不带 BOM 的 UTF-8
  1. 你必须xml一个实例而不是class定义
  2. 要获得 Unicode,您必须声明一个 XmlWriter 或 TextWriter
FileStream stream = new FileStream(myPath, FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(myClass));
XmlWriter writer = new XmlTextWriter(fs, Encoding.Unicode);
serializer.Serialize(writer, myClass);
stream.Close();