Die ordnungsgemäße Objektentsorgung wurde der Kürze halber entfernt, aber ich bin schockiert, wenn dies der einfachste Weg ist, ein Objekt als UTF-8 im Speicher zu codieren. Es muss einen einfacheren Weg geben, nicht wahr?
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
Garry Shutler
quelle
quelle
utf8EncodedXml
wie UTF-16.Antworten:
Ihr Code speichert UTF-8 nicht im Speicher, wenn Sie es erneut in eine Zeichenfolge zurücklesen. Daher ist es nicht mehr in UTF-8, sondern in UTF-16 (obwohl es idealerweise am besten ist, Zeichenfolgen auf einer höheren Ebene als zu berücksichtigen jede Kodierung, außer wenn sie dazu gezwungen wird).
Um die tatsächlichen UTF-8-Oktette zu erhalten, können Sie Folgendes verwenden:
Ich habe die gleiche Entsorgung ausgelassen, die Sie übrig haben. Ich bevorzuge leicht Folgendes (bei normaler Entsorgung):
Das ist ungefähr die gleiche Komplexität, zeigt aber, dass es in jeder Phase eine vernünftige Wahl gibt, etwas anderes zu tun, von dem die dringendste darin besteht, an einen anderen Ort als in den Speicher zu serialisieren, z. B. in eine Datei, TCP / IP Stream, Datenbank usw. Alles in allem ist es nicht wirklich so ausführlich.
quelle
XmlWriter.Create(memoryStream, new XmlWriterSettings { Encoding = new UTF8Encoding(false) })
.Nein, Sie können a verwenden
StringWriter
, um das Zwischenprodukt loszuwerdenMemoryStream
. Um es jedoch in XML zu erzwingen, müssen Sie ein verwenden,StringWriter
das dieEncoding
Eigenschaft überschreibt :Oder wenn Sie C # 6 noch nicht verwenden:
Dann:
Natürlich können Sie
Utf8StringWriter
eine allgemeinere Klasse erstellen, die jede Codierung in ihrem Konstruktor akzeptiert - aber meiner Erfahrung nach ist UTF-8 bei weitem die am häufigsten erforderliche "benutzerdefinierte" Codierung für eineStringWriter
:)Nun, wie Jon Hanna sagt, wird dies intern immer noch UTF-16 sein, aber vermutlich werden Sie es irgendwann an etwas anderes übergeben, um es in Binärdaten umzuwandeln ... an diesem Punkt können Sie die obige Zeichenfolge verwenden, Konvertieren Sie es in UTF-8-Bytes, und alles wird gut - da in der XML-Deklaration "utf-8" als Codierung angegeben wird.
EDIT: Ein kurzes, aber vollständiges Beispiel, um diese Arbeitsweise zu zeigen:
Ergebnis:
Beachten Sie die deklarierte Codierung von "utf-8", die wir meiner Meinung nach wollten.
quelle
TextWriter.Encoding
Eigenschaft wird vom XML-Serializer verwendet, um zu bestimmen, welcher Codierungsname im Dokument selbst angegeben werden soll.XmlWriter
dies jedoch mit der Factory-Methode erstellen , die einXmlWriterSettings
Objekt übernimmt , und dieOmitXmlDeclaration
Eigenschaft auf festgelegt isttrue
.Utf8StringWriter
Lösung ist sehr schön und sauberSehr gute Antwort mit Vererbung, denken Sie daran, den Initialisierer zu überschreiben
quelle
Ich habe diesen Blog-Beitrag gefunden, der das Problem sehr gut erklärt und einige verschiedene Lösungen definiert:
(toter Link entfernt)
Ich habe mich mit der Idee zufrieden gegeben, dass der beste Weg, dies zu tun, darin besteht, die XML-Deklaration im Speicher vollständig wegzulassen. Es tatsächlich ist UTF-16 an diesem Punkt sowieso, aber die XML - Deklaration scheint nicht sinnvoll , bis sie mit einer bestimmten Codierung in eine Datei geschrieben wurden; und selbst dann ist die Erklärung nicht erforderlich. Zumindest scheint es die Deserialisierung nicht zu brechen.
Wie @Jon Hanna erwähnt, kann dies mit einem XmlWriter erfolgen, der wie folgt erstellt wurde:
quelle