使用 XmlTextWriter 和 ISO-8859-1 编码编写 XML 文件
本文关键字:XML 文件 编码 XmlTextWriter ISO-8859-1 使用 | 更新日期: 2023-09-27 17:47:21
我在使用 C# 将挪威语字符写入 XML 文件时遇到问题。我有一个字符串变量,其中包含一些挪威语文本(带有 æøå 等字母)。
我正在使用 XmlTextWriter 编写 XML,将内容写入 MemoryStream,如下所示:
MemoryStream stream = new MemoryStream();
XmlTextWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.GetEncoding("ISO-8859-1"));
xmlTextWriter.Formatting = Formatting.Indented;
xmlTextWriter.WriteStartDocument(); //Start doc
然后我像这样添加我的挪威语文本:
xmlTextWriter.WriteCData(myNorwegianText);
然后我像这样将文件写入磁盘:
FileStream myFile = new FileStream(myPath, FileMode.Create);
StreamWriter sw = new StreamWriter(myFile);
stream.Position = 0;
StreamReader sr = new StreamReader(stream);
string content = sr.ReadToEnd();
sw.Write(content);
sw.Flush();
myFile.Flush();
myFile.Close();
现在的问题是,在文件中,所有的挪威角色看起来都很有趣。
我可能正在以某种愚蠢的方式做上述事情。关于如何解决它的任何建议?
为什么先将 XML 写入 MemoryStream,然后再将其写入实际的文件流?这是相当低效的。如果您直接写入文件流,它应该可以工作。
如果您仍然想进行双重写入,无论出于何种原因,请执行以下两件事之一。也
-
确保您使用的 StreamReader 和 StreamWriter 对象都使用与您与 XmlWriter 一起使用的编码相同的编码(而不仅仅是其他人建议的 StreamWriter),或者
-
不要使用 StreamReader/StreamWriter。相反,只需使用简单的 byte[] 和 Stream.Read/Write 在字节级别复制流。顺便说一句,无论如何,这将更有效率。
您的 StreamWriter 和 StreamReader 都使用 UTF-8,因为您没有指定编码。这就是为什么事情被破坏的原因。
正如tomasr所说,使用FileStream开始会更简单 - 但MemoryStream也有方便的"WriteTo"方法,可以让你非常轻松地将其复制到FileStream。
顺便说一下,我希望你在真实代码中有一个 using 语句 - 如果你在写入文件句柄时出现问题,你不想让你的文件句柄保持打开状态。
乔恩
每次写入字符串或将二进制数据读取为字符串时,都需要设置编码。
Encoding encoding = Encoding.GetEncoding("ISO-8859-1");
FileStream myFile = new FileStream(myPath, FileMode.Create);
StreamWriter sw = new StreamWriter(myFile, encoding);
stream.Position = 0;
StreamReader sr = new StreamReader(stream, encoding);
string content = sr.ReadToEnd();
sw.Write(content);
sw.Flush();
myFile.Flush();
myFile.Close();
如上述答案所述,这里最大的问题是 Encoding
,由于未指定而默认。
如果未为此类转换指定Encoding
,则使用默认值 UTF-8
- 这可能与您的方案匹配,也可能不匹配。您还通过将其推送到MemoryStream
然后推出FileStream
来不必要地转换数据。
如果您的原始数据未UTF-8
,这里将发生的情况是,第一次转换到MemoryStream
将尝试使用默认Encoding
UTF-8
进行解码 - 并因此损坏您的数据。然后写出到FileStream
,默认情况下也使用UTF-8
作为编码,您只需将损坏保存到文件中即可。
为了解决此问题,您可能需要在Stream
对象中指定Encoding
。
您实际上也可以完全跳过MemoryStream
过程 - 这将更快,更高效。更新后的代码可能更像:
FileStream fs = new FileStream(myPath, FileMode.Create);
XmlTextWriter xmlTextWriter =
new XmlTextWriter(fs, Encoding.GetEncoding("ISO-8859-1"));
xmlTextWriter.Formatting = Formatting.Indented;
xmlTextWriter.WriteStartDocument(); //Start doc
xmlTextWriter.WriteCData(myNorwegianText);
StreamWriter sw = new StreamWriter(fs);
fs.Position = 0;
StreamReader sr = new StreamReader(fs);
string content = sr.ReadToEnd();
sw.Write(content);
sw.Flush();
fs.Flush();
fs.Close();
您使用哪种编码来显示结果文件?如果它不在 ISO-8859-1 中,它将无法正确显示。
是否有理由使用此特定编码,而不是例如 UTF8?
经过调查,这是最适合我的:
var doc = new XDocument(new XDeclaration("1.0", "ISO-8859-1", ""));
using (XmlWriter writer = doc.CreateWriter()){
writer.WriteStartDocument();
writer.WriteStartElement("Root");
writer.WriteElementString("Foo", "value");
writer.WriteEndElement();
writer.WriteEndDocument();
}
doc.Save("dte.xml");