Написание 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, он должен работать.

Если вы все еще хотите сделать двойную запись, по какой-либо причине сделайте одну из двух вещей. Либо

  1. убедитесь, что объекты StreamReader и StreamWriter используются все использовать то же самое кодирования, используемой при XmlWriter (не только StreamWriter, как кто-то другой предложил), или

  2. не использовать поток 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");