Написание XML-файлов с помощью XmlTextWriter с кодировкой ISO-8859-1
у меня проблема с записью норвежских символов в XML-файл с помощью C#. У меня есть строковая переменная, содержащая норвежский текст (с буквами, такими как æøå).
Я пишу XML с помощью XmlTextWriter, записывая содержимое в 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();
Теперь проблема в том, что в файл на этом все Норвежские персонажи выглядят забавно.
Я, вероятно, делаю это каким-то глупым образом. Любые предложения о том, как это исправить?
6 ответов
Почему вы сначала пишете XML в MemoryStream, а затем записываете это в фактический поток файлов? Это довольно неэффективно. Если вы пишете непосредственно в FileStream, он должен работать.
Если вы все еще хотите сделать двойную запись, по какой-либо причине сделайте одну из двух вещей. Либо
убедитесь, что объекты StreamReader и StreamWriter используются все использовать то же самое кодирования, используемой при XmlWriter (не только StreamWriter, как кто-то другой предложил), или
не использовать поток streamreader/модулю записи StreamWriter. Вместо этого просто скопируйте поток на уровне байтов, используя простой byte[] и Stream.чтение-запись. Это будет, кстати, намного эффективнее в любом случае.
и ваш 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
попытается декодировать с помощью default Encoding
of UTF-8
- и испортить ваши данные в результате. Когда вы пишите на 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();
какую кодировку вы используете для отображения файла результатов? Если он не находится в 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");