Правильная утилизация объекта удалена для краткости, но я шокирован, если это самый простой способ кодировать объект как UTF-8 в памяти. Должен быть способ попроще, не так ли?
var serializer = new XmlSerializer(typeof(SomeSerializableObject));
var memoryStream = new MemoryStream();
var streamWriter = new StreamWriter(memoryStream, System.Text.Encoding.UTF8);
serializer.Serialize(streamWriter, entry);
memoryStream.Seek(0, SeekOrigin.Begin);
var streamReader = new StreamReader(memoryStream, System.Text.Encoding.UTF8);
var utf8EncodedXml = streamReader.ReadToEnd();
c#
xml
utf-8
xml-serialization
Гарри Шатлер
источник
источник
utf8EncodedXml
как и UTF-16.Ответы:
Ваш код не помещает UTF-8 в память, когда вы снова читаете его обратно в строку, поэтому его больше не в UTF-8, а обратно в UTF-16 (хотя в идеале лучше всего рассматривать строки на более высоком уровне, чем любая кодировка, кроме случаев, когда это принудительно).
Чтобы получить фактические октеты UTF-8, вы можете использовать:
Я не учел то же самое, что и ты. Я немного предпочитаю следующее (оставив обычную утилизацию):
Это примерно такая же сложность, но показывает, что на каждом этапе есть разумный выбор сделать что-то еще, наиболее актуальным из которых является сериализация в другое место, а не в память, например, в файл, TCP / IP. поток, база данных и т. д. В общем, это не так уж и много подробностей.
источник
XmlWriter.Create(memoryStream, new XmlWriterSettings { Encoding = new UTF8Encoding(false) })
.Нет, вы можете использовать a,
StringWriter
чтобы избавиться от промежуточного звенаMemoryStream
. Однако, чтобы принудительно преобразовать его в XML, вам нужно использовать,StringWriter
который переопределяетEncoding
свойство:Или, если вы еще не используете C # 6:
Затем:
Очевидно, вы можете создать
Utf8StringWriter
более общий класс, который принимает любую кодировку в своем конструкторе, но, по моему опыту, UTF-8 является наиболее часто требуемой "пользовательской" кодировкой для aStringWriter
:)Теперь, как говорит Джон Ханна, внутренне это все еще будет UTF-16, но, предположительно, в какой-то момент вы собираетесь передать его чему-то еще, чтобы преобразовать его в двоичные данные ... в этот момент вы можете использовать указанную выше строку, преобразуйте его в байты UTF-8, и все будет хорошо, потому что объявление XML будет указывать в качестве кодировки «utf-8».
РЕДАКТИРОВАТЬ: короткий, но полный пример, показывающий, как это работает:
Результат:
Обратите внимание на заявленную кодировку «utf-8», что, я считаю, именно то, что мы хотели.
источник
TextWriter.Encoding
свойство используется сериализатором XML для определения имени кодировки, которое следует указать в самом документе.XmlWriter
сделайте это с помощью фабричного метода, который принимаетXmlWriterSettings
объект и дляOmitXmlDeclaration
свойства установлено значениеtrue
.Utf8StringWriter
решение очень красивое и чистоеОчень хороший ответ с использованием наследования, просто не забудьте переопределить инициализатор
источник
Я нашел это сообщение в блоге, которое очень хорошо объясняет проблему и определяет несколько различных решений:
(мертвая ссылка удалена)
Я пришел к выводу, что лучший способ сделать это - полностью опустить объявление XML в памяти. Это на самом деле является UTF-16 в этот момент так или иначе, но декларация XML не представляется значимой , пока он не был записан в файл с определенной кодировкой; да и то декларация не требуется. По крайней мере, это не мешает десериализации.
Как упоминает @Jon Hanna, это можно сделать с помощью XmlWriter, созданного следующим образом:
источник