Pembuangan objek yang tepat dihapus agar singkat tetapi saya terkejut jika ini adalah cara paling sederhana untuk menyandikan objek sebagai UTF-8 dalam memori. Pasti ada cara yang lebih mudah bukan?
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
sumber
sumber
utf8EncodedXml
juga UTF-16.Jawaban:
Kode Anda tidak memasukkan UTF-8 ke dalam memori saat Anda membacanya kembali menjadi string lagi, jadi tidak lagi dalam UTF-8, tetapi kembali dalam UTF-16 (meskipun idealnya yang terbaik untuk mempertimbangkan string pada tingkat yang lebih tinggi daripada pengkodean apa pun, kecuali jika dipaksa untuk melakukannya).
Untuk mendapatkan oktet UTF-8 yang sebenarnya, Anda dapat menggunakan:
Saya telah meninggalkan pembuangan yang sama dengan yang Anda tinggalkan. Saya sedikit menyukai yang berikut (dengan pembuangan normal tersisa):
Yang merupakan jumlah kompleksitas yang sama, tetapi menunjukkan bahwa pada setiap tahap ada pilihan yang masuk akal untuk melakukan sesuatu yang lain, yang paling mendesak adalah melakukan serialisasi ke tempat lain selain ke memori, seperti ke file, TCP / IP streaming, database, dll. Secara keseluruhan, ini tidak terlalu bertele-tele.
sumber
XmlWriter.Create(memoryStream, new XmlWriterSettings { Encoding = new UTF8Encoding(false) })
.Tidak, Anda dapat menggunakan a
StringWriter
untuk menghilangkan perantaraMemoryStream
. Namun, untuk memaksanya ke dalam XML, Anda perlu menggunakan aStringWriter
yang menggantikanEncoding
properti:Atau jika Anda belum menggunakan C # 6:
Kemudian:
Jelas Anda dapat membuat
Utf8StringWriter
kelas yang lebih umum yang menerima pengkodean apa pun dalam konstruktornya - tetapi menurut pengalaman saya UTF-8 sejauh ini merupakan pengkodean "khusus" yang paling umum diperlukan untukStringWriter
:)Sekarang sebagai Jon Hanna mengatakan, ini masih akan UTF-16 internal, tapi mungkin Anda akan menyebarkannya ke sesuatu yang lain di beberapa titik, untuk mengubahnya menjadi data biner ... pada yang titik Anda dapat menggunakan string di atas, mengonversinya menjadi byte UTF-8, dan semuanya akan baik-baik saja - karena deklarasi XML akan menentukan "utf-8" sebagai pengkodeannya.
EDIT: Contoh singkat tapi lengkap untuk menunjukkan ini berfungsi:
Hasil:
Perhatikan pengkodean yang dideklarasikan dari "utf-8" yang kami inginkan, saya yakin.
sumber
TextWriter.Encoding
properti digunakan oleh serializer XML untuk menentukan nama encoding untuk menentukan dalam dokumen itu sendiri.XmlWriter
do dengan metode pabrik yang mengambilXmlWriterSettings
objek, danOmitXmlDeclaration
menyetel properti ketrue
.Utf8StringWriter
Solusi Anda sangat bagus dan bersihJawaban yang sangat bagus menggunakan pewarisan, ingatlah untuk mengganti penginisialisasi
sumber
Saya menemukan entri blog ini yang menjelaskan masalahnya dengan sangat baik, dan menjelaskan beberapa solusi berbeda:
(tautan mati dihapus)
Saya telah menetapkan gagasan bahwa cara terbaik untuk melakukannya adalah dengan sepenuhnya menghilangkan deklarasi XML saat berada di memori. Ini sebenarnya adalah UTF-16 pada saat itu pula, tapi deklarasi XML tampaknya tidak bermakna sampai telah ditulis ke file dengan encoding tertentu; dan bahkan deklarasi tersebut tidak diperlukan. Tampaknya tidak merusak deserialisasi, setidaknya.
Seperti yang disebutkan @Jon Hanna, ini dapat dilakukan dengan XmlWriter yang dibuat seperti ini:
sumber