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
- 你必须xml一个实例而不是class定义
- 要获得 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();
我正在使用此代码存储我的 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- 你必须xml一个实例而不是class定义
- 要获得 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();