2008-09-26 66 views
16

我有一个问题,使用C#将挪威语字符写入XML文件。我有一个包含一些挪威文字的字符串变量(带有字母)。使用ISO-8859-1编码使用XmlTextWriter编写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(); 

现在的问题是,在这个文件中,所有的Norw egian角色看起来很有趣。

我可能以某种愚蠢的方式做到了上述。有关如何修复它的任何建议?

+0

记住,你也可以使用更通用的UTF-16编码写挪威字符。 – 2009-03-12 11:07:16

回答

13

为什么要先将XML写入MemoryStream然后将其写入实际的文件流?这相当低效。如果你直接写入FileStream它应该工作。

如果你仍然想做双重写,无论出于何种原因,做两件事之一。无论是

  1. 确保的StreamReader和StreamWriter对象使用所有使用相同编码,你用XmlWriter中使用的(不仅仅是StreamWriter的,像其他人建议),或

  2. 请勿使用StreamReader/StreamWriter。而不是仅仅流在字节级使用简单的byte []和拷贝Stream.Read/Write。无论如何,这将是,顺便说一句,效率更高。

+3

写入内存流的一个原因是因为这样做会产生原子操作。看看这篇文章的更多细节:http://aspalliance.com/1012_how_to_write_atomic_transactions_in_net – Dscoduc 2009-01-07 20:34:39

3

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

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

13

无论你的StreamWriter和你的StreamReader使用UTF-8,因为你没有指定的编码。这就是为什么事情越来越损坏。

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

我希望你有一个使用的语句在真正的代码,顺便说一句 - 你不想离开你的文件处理打开的,如果当你写它不顺心的事。

Jon

7

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

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-8Encoding解码 - 毁坏你的数据结果。然后,当您写出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(); 
+0

虽然你正确的方式你有措辞有点混乱,因为他确实在xmltextwriter中指定的编码。 但是,正如你所说的,他没有将它设置在他以后创建的新流中,并且在此之后它不会从源流中读取它,而是恢复默认值 – MikeT 2013-06-05 14:54:50

0

调查后发现,这是为我工作最好的:

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