【问题标题】:Writing XML files using XmlTextWriter with ISO-8859-1 encoding使用 ISO-8859-1 编码的 XmlTextWriter 编写 XML 文件
【发布时间】:2010-09-13 10:43:54
【问题描述】:

我在使用 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();

现在的问题是,在这个文件中,所有的挪威字符看起来都很有趣。

我可能以某种愚蠢的方式执行上述操作。关于如何修复它的任何建议?

【问题讨论】:

  • 请记住,您还可以使用更通用的 UTF-16 编码来编写挪威字符。

标签: c# .net xml encoding iso-8859-1


【解决方案1】:

您使用哪种编码来显示结果文件?如果不在 ISO-8859-1 中,将无法正确显示。

是否有理由使用这种特定的编码,而不是例如 UTF8?

【讨论】:

    【解决方案2】:

    为什么要先将 XML 写入 MemoryStream,然后再将其写入实际的文件流?那是相当低效的。如果您直接写入 FileStream 它应该可以工作。

    如果您仍想执行双重写入,无论出于何种原因,请执行以下两项操作之一。要么

    1. 确保您使用的 StreamReader 和 StreamWriter 对象 all 使用与 XmlWriter 一起使用的 same 编码(不仅仅是 StreamWriter,例如其他人建议),或

    2. 不要使用 StreamReader/StreamWriter。相反,只需使用简单的 byte[] 和 Stream.Read/Write 在字节级别复制流。顺便说一句,这无论如何都会变得更有效率。

    【讨论】:

    【解决方案3】:

    您的 StreamWriter 和 StreamReader 都使用 UTF-8,因为您没有指定编码。这就是事情被破坏的原因。

    正如 tomasr 所说,使用 FileStream 开始会更简单 - 而且 MemoryStream 具有方便的“WriteTo”方法,可以让您非常轻松地将其复制到 FileStream。

    顺便说一句,我希望你的真实代码中有一个 using 语句 - 如果在写入文件时出现问题,你不想让文件句柄保持打开状态。

    乔恩

    【讨论】:

      【解决方案4】:

      每次写入字符串或将二进制数据读取为字符串时都需要设置编码。

          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();
      

      【讨论】:

        【解决方案5】:

        正如上面的答案中提到的,这里最大的问题是Encoding,由于未指定而被默认。

        当您没有为此类转换指定 Encoding 时,将使用默认值 UTF-8 - 这可能与您的场景匹配,也可能不匹配。您还通过将数据推送到 MemoryStream 然后将其推送到 FileStream 来不必要地转换数据。

        如果您的原始数据不是UTF-8,那么这里会发生的情况是,第一次转换到MemoryStream 将尝试使用UTF-8 的默认Encoding 进行解码,结果会损坏您的数据。然后,当您写入FileStream(默认情况下也使用UTF-8 作为编码)时,您只需将损坏保存到文件中即可。

        为了解决此问题,您可能需要将 Encoding 指定到您的 Stream 对象中。

        实际上,您也可以完全跳过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();
        

        【讨论】:

        • 虽然你的措辞是正确的,但有点令人困惑,因为他确实在 xmltextwriter 中指定了编码。但正如你所说,他没有在他后来创建的新流中设置它,没有这个它不会从源流中读取它,而是恢复默认值
        【解决方案6】:

        经过调查,这是最适合我的:

        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");
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多