سؤال

أواجه مشكلة في كتابة الأحرف النرويجية في ملف 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();

المشكلة الآن هي أن جميع الشخصيات النرويجية في الملف تبدو مضحكة.

ربما أفعل ما سبق بطريقة غبية.أي اقتراحات حول كيفية إصلاح ذلك؟

هل كانت مفيدة؟

المحلول

لماذا تكتب XML أولاً إلى MemoryStream ثم تكتب ذلك إلى دفق الملف الفعلي؟هذا غير فعال إلى حد ما.إذا كتبت مباشرة إلى FileStream فيجب أن تعمل.

إذا كنت لا تزال ترغب في القيام بالكتابة المزدوجة، لأي سبب من الأسباب، فقم بأحد الأمرين.أيضاً

  1. تأكد من أن الكائنات StreamReader وStreamWriter التي تستخدمها الجميع استخدم ال نفس التشفير الذي استخدمته مع XmlWriter (وليس فقط StreamWriter، كما اقترح شخص آخر)، أو

  2. لا تستخدم StreamReader/StreamWriter.بدلاً من ذلك، ما عليك سوى نسخ الدفق على مستوى البايت باستخدام بايت بسيط[] وStream.Read/Write.سيكون هذا، بالمناسبة، أكثر كفاءة على أي حال.

نصائح أخرى

يستخدم كل من StreamWriter وStreamReader UTF-8، لأنك لا تحدد التشفير.ولهذا السبب تفسد الأمور.

كما قال توماسر، فإن استخدام FileStream للبدء به سيكون أسهل - ولكن يحتوي MemoryStream أيضًا على طريقة "WriteTo" سهلة الاستخدام والتي تتيح لك نسخه إلى FileStream بسهولة شديدة.

أتمنى أن تكون قد حصلت على عبارة استخدام في شفرتك الحقيقية، بالمناسبة - فأنت لا تريد ترك مقبض الملف مفتوحًا إذا حدث خطأ ما أثناء الكتابة إليه.

جون

تحتاج إلى ضبط التشفير في كل مرة تكتب فيها سلسلة أو تقرأ البيانات الثنائية كسلسلة.

    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 سيحاول فك التشفير باستخدام الافتراضي Encoding ل 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");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top