عند مواجهة تيار من البايتات ، لا يمكن معروفة معناها الفعلي دون تحديد ترميزه.
يجب أن تكون هذه الجملة أيضًا ما نتذكره دائمًا في أذهاننا عند مواجهة مشكلة "الشخصية إلى البايت ، بايت إلى الشخصية". خلاف ذلك ، قد تتبع المشاكل المشوهة.
في الواقع ، فإن جوهر المشكلة المشوهة هو أن الترميز وفك التشفير لا يستخدم نفس الترميز. إذا فهمت هذا المبدأ ، فمن السهل حل المشكلة المشوهة.
شائع الاستخدام في Java على النحو التالي:
1. يستخدم فئة السلسلة سلسلة مُنشئ (بايت [] بايت) من البايت []. توفر فئة السلسلة تحميلين زائدين في نفس الوقت (1) سلسلة (بايت [] بايت ، شارت تشارسيت)
(2) يتم استخدام السلسلة (بايت [] بايت ، سلسلة charsetName) لتحديد الترميز.
2. دالة getBytes بايت [] getBytes () من فئة السلسلة لديها أيضا اثنين من الأحمال الزائدة:
(1) بايت [] getBytes (Charset Charset)
(2) بايت [] getBytes (سلسلة charsetname)
يتم الحصول على كل ما لا يتطلب الترميز المحدد باستخدام charset الافتراضي للنظام الأساسي ، والذي يمكن الحصول عليه باستخدام system.getProperty ("file.encoding") ، charset.defaultcharset ().
3. تم تصميم طباعة PrintStream (سلسلة S) لهذه المشكلة. لهذا السبب ، فإن مُنشئ PrintStream ليس فقط printstream (ملف الملف) و printstream (ملف الملف ، السلسلة CSN)
وإلا يتم تحويل أحرف السلسلة إلى بايت وفقًا لترميز الأحرف الافتراضية للنظام الأساسي ،
لا يحتوي بناء DataOutputStream على طريقة لتحديد الترميز ، ولكنه يوفر كتابة (String Str)
أعط الأمثلة في البداية لتوضيح الحاجة إلى تحديد الترميز:
إذا تحدد صفحة ويب الترميز كـ UTF-8 ، <meta http-equiv = "content-type" content = "text /html ؛ charset = utf-8" /> ، يوجد نموذج على الصفحة ، مقدمة إلى servlet
ثم يتم ترميز دفق البايت الذي تم تمريره بواسطة الأحرف التي يدخلها المستخدم وفقًا للترميز المحدد. على سبيل المثال ، إذا قمت بإدخال "Hello Hello" ، إذا كان UTF-8 ، فإن إرساله هو كما يلي:
[104 ، 101 ، 108 ، 108 ، 111 ، -28 ، -67 ، -96 ، -27 ، -91 ، -67]
، نرى أن كل من الأحرف الصينية التالية يستخدم 3 بايت ، والتي يمكن استخدامها للإشارة إلى المعرفة ذات الصلة بـ UTF-8.
ولكن إذا حددت صفحتك GBK ، فسيكون الإرسال مختلفًا:
[104 ، 101 ، 108 ، 108 ، 111 ، -60 ، -29 ، -70 ، -61]
لذلك ، عند استخدام request.getParameter على جانب servlet ، يجب أن يطلق عليه داخليًا
سلسلة s = سلسلة جديدة (بايت ، استجابة. getEncoding ()). إذا لم يتم ضبط ردك على الترميز ، فسيتم تحويل NULL الترميز الافتراضي إلى GBK لمنصة Java ، وبعد ذلك سيصبح الصينيون مشوهين.
لذلك ، من أجل تجنب الكود المشوهة ، تقوم مواقع JSP بتعيين مرشح بشكل عام ، ويتم تعيين جميع الصفحات والخدمات لتشفير موحد. استجابة.
Inside Java String عبارة عن char [] ، وهي وحدة مشفرة مع UTF-16 المخزنة 16 بت. تحقيقًا لهذه الغاية ، عند تحويل الأحرف والسلاسل إلى بايت وإخراجها إلى الملفات أو الشبكات ، أو إعادة تدفقات البايت القراءة من الملفات أو الشبكات إلى الأحرف ذات الأهمية العملية ، يجب أن تفهم ماهية ترميزها.
بعض التجارب
1. يتم تخزين فئة السلسلة دائمًا في ترميز Unicode.
2. انتبه لاستخدام string.getBytes ():
إذا لم يتم تضمين معلمة مجموعة الأحرف ، فسوف تعتمد على ترميز مجموعة الأحرف لـ JVM. إنه عمومًا يونيكود على Linux ، و GBK تحت Windows. (إذا كنت تريد تغيير ترميز مجموعة الأحرف الافتراضية لـ JVM ، فاستخدم الخيار -dfile.encodeing = UTF -8 عند بدء تشغيل JVM.
لأسباب تتعلق بالسلامة ، يوصى الاتصال دائمًا بالمعلمات ، على سبيل المثال: السلسلة S ؛ S.GetBytes ("UTF-8").
3. فئة Charset مفيدة للغاية.
(1) تشفير charset.encode ، أي ترميز السلسلة بتنسيق ترميز مجموعة الأحرف التي تحددها وإخراج مجموعة بايت.
(2) charset.decode هو فك التشفير ، أي فك تشفير مجموعة بايت في تنسيق ترميز مجموعة الأحرف التي تحددها وإخراجها في سلسلة.
كمثال:
String s = charset.defaultcharset (). displayName () ؛ السلسلة S1 = "أنا معجب بك يا حبيبتي" ؛ bytebuffer bb1 = bytebuffer.wrap (s1.getBytes ("utf-8")) ؛ لـ (byte bt: bb1.array ()) {system.out.printf ("٪ x" ، bt) ؛ } // char [] use char [] charray = {'i' ، 'l' ، 'o' ، 'v' ، 'e' ، you '} ؛ // Charbuffer use Charbuffer CB = Charbuffer.wrap (Charray) ؛ // إعادة تحديد موقع مؤشر cb.flip () ؛ السلسلة S2 = سلسلة جديدة (Charray) ؛ // Bytebuffer use Bytebuffer BB2 = charset.forname ("UTF-8"). Encode (CB) ؛ // استخدم charset لتشفير كحرف محدد تعيين bytebuffer bb3 = charset.forname ("utf-8"). encode (S1) ؛ بايت [] b = bb3.array () ؛ // استخدم charset لفك تشفيرها كسلسلة وفقًا للحرف المحددة التي تم تعيينها bytebuffer bb4 = bytebuffer.wrap (b) ؛ String S2 = charset.forname ("UTF-8"). فك الشفرة (BB4) .ToString () ؛