คอมพิวเตอร์ Windows อินเทอร์เน็ต

ตัวอักษรรัสเซียในตารางรหัส windows การเข้ารหัสซิริลลิก - รัสเซีย

การเข้ารหัส

เมื่อฉันเริ่มเขียนโปรแกรมในภาษา C โปรแกรมแรกของฉัน (นอกเหนือจาก HelloWorld) เป็นโปรแกรมแปลงรหัส ไฟล์ข้อความจากการเข้ารหัส GOST หลัก (จำอันนี้ได้ไหม :-) ไปจนถึงตัวอื่น ย้อนกลับไปในปี 1991 มีการเปลี่ยนแปลงมากมายตั้งแต่นั้นมา แต่น่าเสียดายที่โปรแกรมดังกล่าวไม่ได้สูญเสียความเกี่ยวข้องตลอด 10 ปีที่ผ่านมา มีการสะสมข้อมูลมากเกินไปในการเข้ารหัสต่างๆ และใช้โปรแกรมมากเกินไปที่สามารถทำงานได้เพียงโปรแกรมเดียว สำหรับภาษารัสเซียนั้น มีการเข้ารหัสที่แตกต่างกันอย่างน้อยสิบแบบ ซึ่งทำให้ปัญหาสับสนมากยิ่งขึ้น

การเข้ารหัสเหล่านี้มาจากไหนและมีไว้เพื่ออะไร โดยธรรมชาติแล้ว คอมพิวเตอร์สามารถทำงานได้กับตัวเลขเท่านั้น เพื่อเก็บตัวอักษรไว้ในหน่วยความจำของคอมพิวเตอร์ จำเป็นต้องกำหนดตัวเลขให้กับตัวอักษรแต่ละตัว ยิ่งไปกว่านั้น จำนวนที่น้อยกว่าที่ควรจะเป็น - ยิ่งมีเลขฐานสองน้อยลงเท่าใดก็ยิ่งสามารถใช้หน่วยความจำได้อย่างมีประสิทธิภาพมากขึ้นเท่านั้น ความสอดคล้องระหว่างชุดของอักขระและตัวเลขนี้เป็นการเข้ารหัสจริงๆ ความปรารถนาที่จะบันทึกหน่วยความจำไม่ว่าจะเสียค่าใช้จ่ายใด ๆ เช่นเดียวกับการแตกแยกของนักวิทยาศาสตร์คอมพิวเตอร์กลุ่มต่าง ๆ นำไปสู่สถานะปัจจุบัน วิธีการเข้ารหัสที่พบบ่อยที่สุดในขณะนี้คือการใช้หนึ่งไบต์ (8 บิต) ต่ออักขระหนึ่งตัว ซึ่งกำหนดจำนวนอักขระทั้งหมดเป็น 256 ตัว ชุดของอักขระ 128 ตัวแรกเป็นมาตรฐาน (ชุด ASCII) และเหมือนกันในการเข้ารหัสทั่วไปทั้งหมด (การเข้ารหัสเหล่านั้นที่ไม่ได้ใช้งานจริงอยู่แล้ว) ตัวอักษรแองกลิกันและสัญลักษณ์เครื่องหมายวรรคตอนอยู่ในช่วงนี้ ซึ่งกำหนดความมีชีวิตชีวาอันน่าทึ่งในระบบคอมพิวเตอร์ :-) ภาษาอื่นไม่ค่อยดีนัก - พวกเขาทั้งหมดต้องรวมกลุ่มกันใน 128 ตัวเลขที่เหลือ

Unicode

ในช่วงปลายทศวรรษ 1980 หลายคนตระหนักถึงความจำเป็นในการสร้างมาตรฐานเดียวสำหรับการเข้ารหัสอักขระ ซึ่งนำไปสู่การเกิดขึ้นของ Unicode Unicode คือความพยายามที่จะแก้ไขตัวเลขเฉพาะสำหรับอักขระตัวใดตัวหนึ่งทันทีและสำหรับทั้งหมด เป็นที่ชัดเจนว่า 256 ตัวอักษรจะไม่พอดีกับความต้องการทั้งหมดที่นี่ เป็นเวลานานดูเหมือนว่า 2 ไบต์ (65536 อักขระ) น่าจะเพียงพอ แต่ไม่ใช่ - เวอร์ชันล่าสุดของมาตรฐาน Unicode (3.1) ได้กำหนดอักขระแล้ว 94,140 ตัว สำหรับจำนวนอักขระดังกล่าว คุณอาจต้องใช้ 4 ไบต์อยู่แล้ว (4294967296 อักขระ) อาจจะเพียงพอในขณะที่ ... :-)

เข้าชุด อักขระ Unicodeรวมตัวอักษรทุกประเภทพร้อมขีดกลางและปาเพนดิลกิ กรีก คณิตศาสตร์ อักษรอียิปต์โบราณ สัญลักษณ์กราฟิกหลอก ฯลฯ ฯลฯ รวมถึงอักขระซีริลลิกที่เราชื่นชอบ (ช่วงของค่าคือ 0x0400-0x04ff) ดังนั้นจึงไม่มีการเลือกปฏิบัติในด้านนี้

หากคุณสนใจรหัสอักขระเฉพาะ จะสะดวกที่จะใช้โปรแกรม "ผังอักขระ" จาก WinNT เพื่อดู ตัวอย่างเช่น นี่คือช่วง Cyrillic:

หากคุณมีระบบปฏิบัติการอื่นหรือสนใจในการตีความอย่างเป็นทางการ สามารถดูแผนภูมิแบบเต็มได้ที่เว็บไซต์ทางการของ Unicode (http://www.unicode.org/charts/web.html)

ประเภทอักขระและไบต์

Java มีประเภทข้อมูลถ่านแยกต่างหาก 2 ไบต์สำหรับอักขระ สิ่งนี้มักจะสร้างความสับสนในใจของผู้เริ่มต้น (โดยเฉพาะอย่างยิ่งหากพวกเขาได้ตั้งโปรแกรมในภาษาอื่นเช่น C / C ++ ก่อนหน้านี้) เนื่องจากภาษาอื่นๆ ส่วนใหญ่ใช้ประเภทข้อมูล 1 ไบต์ในการประมวลผลอักขระ ตัวอย่างเช่น ใน C / C ++ ถ่านส่วนใหญ่จะใช้สำหรับการจัดการอักขระและการจัดการไบต์ - ไม่มีการแยก Java มีประเภทของตัวเองสำหรับไบต์ - ประเภทไบต์ ดังนั้น ถ่านแบบ C จึงสอดคล้องกับไบต์ของ Java และถ่าน Java จากโลก C นั้นใกล้เคียงกับประเภท wchar_t มากที่สุด จำเป็นต้องแยกแนวคิดของอักขระและไบต์ออกอย่างชัดเจน ไม่เช่นนั้นจะรับประกันความเข้าใจผิดและปัญหา

Java ใช้สำหรับการเข้ารหัสอักขระมาเกือบตั้งแต่เริ่มก่อตั้ง มาตรฐานยูนิโค้ด... ฟังก์ชันไลบรารี Java คาดว่าจะเห็นอักขระอักขระแทนโดย รหัส Unicode... โดยหลักการแล้ว คุณสามารถใส่อะไรก็ได้ - ตัวเลขคือตัวเลข โปรเซสเซอร์จะทนทุกอย่าง แต่สำหรับการประมวลผลใดๆ ฟังก์ชันไลบรารีจะทำหน้าที่ตามสมมติฐานที่ได้รับ การเข้ารหัส Unicode... ดังนั้นคุณจึงสามารถสรุปได้อย่างปลอดภัยว่าการเข้ารหัสอักขระนั้นได้รับการแก้ไขแล้ว แต่นี่อยู่ใน JVM เมื่อข้อมูลถูกอ่านจากภายนอกหรือส่งผ่านภายนอก จะสามารถแสดงได้เพียงประเภทเดียวเท่านั้น - ประเภทไบต์ ประเภทอื่นๆ ทั้งหมดสร้างขึ้นจากไบต์ ขึ้นอยู่กับรูปแบบข้อมูลที่ใช้ นี่คือจุดเริ่มต้นของการเข้ารหัส - ใน Java เป็นเพียงรูปแบบข้อมูลสำหรับการถ่ายโอนอักขระซึ่งใช้เพื่อสร้างข้อมูลประเภทถ่าน สำหรับแต่ละโค้ดเพจ ไลบรารีมีคลาสการแปลง 2 คลาส (ByteToChar และ CharToByte) คลาสเหล่านี้อยู่ในแพ็คเกจ sun.io หากไม่พบอักขระที่สอดคล้องกันเมื่อแปลงจากถ่านเป็นไบต์จะถูกแทนที่ด้วยอักขระ ?

อย่างไรก็ตาม ไฟล์โค้ดเพจเหล่านี้ใน JDK 1.1 เวอร์ชันแรกๆ บางเวอร์ชันมีข้อบกพร่องที่ทำให้เกิดข้อผิดพลาดในการแปลงหรือแม้แต่ข้อยกเว้นรันไทม์ ตัวอย่างเช่น สิ่งนี้เกี่ยวข้องกับการเข้ารหัส KOI8_R สิ่งที่ดีที่สุดที่ควรทำขณะทำเช่นนี้คือการอัปเกรดเป็นเวอร์ชันที่ใหม่กว่า เมื่อพิจารณาจากคำอธิบายของ Sun ปัญหาเหล่านี้ส่วนใหญ่ได้รับการแก้ไขแล้วใน JDK 1.1.6

ก่อน JDK 1.4 ชุดของการเข้ารหัสที่ใช้ได้ถูกกำหนดโดยผู้จำหน่าย JDK เท่านั้น เริ่มต้นด้วย 1.4 API ใหม่ได้ปรากฏขึ้นแล้ว (แพ็คเกจ java.nio.charset) ซึ่งคุณสามารถสร้างการเข้ารหัสของคุณเองได้ (เช่น รองรับโปรแกรมที่ไม่ค่อยได้ใช้ แต่จำเป็นอย่างยิ่งสำหรับคุณ)

คลาสสตริง

ในกรณีส่วนใหญ่ Java จะใช้อ็อบเจ็กต์ประเภท java.lang.String เพื่อแสดงสตริง นี่คือคลาสปกติที่เก็บอาร์เรย์ของอักขระ (char) ไว้ภายในและมีวิธีการที่มีประโยชน์มากมายสำหรับการจัดการอักขระ สิ่งที่น่าสนใจที่สุดคือตัวสร้างที่มีอาร์เรย์ไบต์เป็นพารามิเตอร์แรกและเมธอด getBytes () ด้วยวิธีการเหล่านี้ คุณสามารถทำการแปลงจากไบต์อาร์เรย์เป็นสตริงได้ และในทางกลับกัน เพื่อระบุการเข้ารหัสที่จะใช้พร้อมกัน เมธอดเหล่านี้มีพารามิเตอร์สตริงที่ตั้งชื่อ ตัวอย่างเช่น วิธีแปลงไบต์จาก KOI-8 เป็น Windows-1251 มีดังนี้

// ข้อมูลที่เข้ารหัส KOI-8ไบต์ koi8Data = ...; // แปลงจาก KOI-8 เป็น Unicodeสตริงสตริง = สตริงใหม่ (koi8Data, "KOI8_R"); // แปลงจาก Unicode เป็น Windows-1251ไบต์ winData = string.getBytes ("Cp1251");

รายการการเข้ารหัส 8 บิตที่มีอยู่ใน JDK สมัยใหม่และตัวอักษรรัสเซียที่รองรับอยู่ด้านล่างในส่วน

เนื่องจากการเข้ารหัสเป็นรูปแบบข้อมูลสำหรับอักขระ นอกเหนือจากการเข้ารหัส 8 บิตที่คุ้นเคยใน Java แล้ว ยังมีการเข้ารหัสแบบหลายไบต์ในระดับที่เท่ากัน ซึ่งรวมถึง UTF-8, UTF-16, Unicode เป็นต้น ตัวอย่างเช่น วิธีรับไบต์ในรูปแบบ UnicodeLittleUnmarked (การเข้ารหัส Unicode 16 บิต ไบต์ต่ำก่อน ไม่มีเครื่องหมายลำดับไบต์):

// แปลงจาก Unicode เป็น Unicodeข้อมูลไบต์ = string.getBytes ("UnicodeLittleUnmarked");

มันง่ายที่จะทำผิดพลาดกับการแปลงดังกล่าว - หากการเข้ารหัสข้อมูลไบต์ไม่ตรงกับพารามิเตอร์ที่ระบุเมื่อแปลงจากไบต์เป็นถ่าน การบันทึกจะไม่ถูกดำเนินการอย่างถูกต้อง บางครั้งหลังจากนั้น คุณสามารถดึงอักขระที่ถูกต้องออกมาได้ แต่บ่อยครั้งกว่านั้น ข้อมูลบางส่วนจะสูญหายไปอย่างแก้ไขไม่ได้

ในโปรแกรมจริง ไม่สะดวกที่จะระบุโค้ดเพจให้ชัดเจนเสมอไป (แม้ว่าจะเชื่อถือได้มากกว่าก็ตาม) ด้วยเหตุนี้จึงมีการแนะนำการเข้ารหัสเริ่มต้น โดยค่าเริ่มต้น ขึ้นอยู่กับระบบและการตั้งค่าของระบบ (สำหรับ Windows รัสเซีย จะใช้การเข้ารหัส Cp1251) และใน JDK รุ่นเก่า สามารถเปลี่ยนได้โดยการตั้งค่าคุณสมบัติของระบบ file.encoding ใน JDK 1.3 การเปลี่ยนการตั้งค่านี้บางครั้งใช้ได้ แต่บางครั้งก็ใช้ไม่ได้ มีสาเหตุดังต่อไปนี้: ในตอนแรก file.encoding ถูกตั้งค่าตามการตั้งค่าภูมิภาคของคอมพิวเตอร์ การอ้างอิงการเข้ารหัสเริ่มต้นจะจดจำไว้ภายในระหว่างการแปลงครั้งแรก ในกรณีนี้ จะใช้ file.encoding แต่การแปลงนี้เกิดขึ้นก่อนการใช้อาร์กิวเมนต์การเริ่มต้น JVM (อันที่จริงแล้ว เมื่อแยกวิเคราะห์) อันที่จริง Sun กล่าวว่าคุณสมบัตินี้สะท้อนถึงการเข้ารหัสของระบบและไม่ควรเปลี่ยนแปลงในบรรทัดคำสั่ง (ดูตัวอย่าง ความคิดเห็นเกี่ยวกับ BugID) อย่างไรก็ตาม ใน JDK 1.4 Beta 2 การเปลี่ยนแปลงการตั้งค่านี้อีกครั้งเริ่มมีผล นี่คือการเปลี่ยนแปลงอย่างมีสติหรือผลข้างเคียงที่สามารถหายไปได้อีกครั้ง - แกะซันยังไม่ได้ให้คำตอบที่ชัดเจน

การเข้ารหัสนี้ใช้เมื่อไม่ได้ระบุชื่อเพจไว้อย่างชัดเจน สิ่งนี้ควรจำไว้เสมอ - Java จะไม่พยายามคาดเดาการเข้ารหัสของไบต์ที่คุณส่งผ่านเพื่อสร้างสตริง (มันจะไม่สามารถอ่านความคิดของคุณเกี่ยวกับ :-) เพียงแค่ใช้การเข้ารหัสเริ่มต้นปัจจุบัน เพราะ การตั้งค่านี้จะเหมือนกันสำหรับการแปลงทั้งหมด บางครั้งคุณอาจประสบปัญหา

ในการแปลงจากไบต์เป็นอักขระและในทางกลับกัน ให้ใช้ เท่านั้นโดยวิธีการเหล่านี้ ในกรณีส่วนใหญ่ การแปลงประเภทอย่างง่ายจะไม่สามารถใช้ได้ - การเข้ารหัสอักขระจะไม่ถูกนำมาพิจารณา ตัวอย่างเช่น หนึ่งในข้อผิดพลาดที่พบบ่อยที่สุดคือการอ่านข้อมูลแบบไบต์โดยใช้เมธอด read () จาก InputStream จากนั้นจึงส่งค่าผลลัพธ์เป็นประเภทถ่าน:

InputStream คือ = ..; int ข; StringBuffer sb = ใหม่ StringBuffer (); ในขณะที่ ((b = is.read ())! = - 1) (sb.append ((char) b); // <- так делать нельзя ) สตริง s = sb.toString ();

ให้ความสนใจกับการพิมพ์ดีด - "(อักขระ) ข" ค่าไบต์จะถูกคัดลอกไปยังถ่านแทนการเข้ารหัสซ้ำ (ช่วงของค่าคือ 0-0xFF ไม่ใช่ช่วงที่มีอักษรซีริลลิก) การคัดลอกนี้สอดคล้องกับการเข้ารหัส ISO-8859-1 (ซึ่งหนึ่งต่อหนึ่งสอดคล้องกับค่า Unicode 256 ค่าแรก) ซึ่งหมายความว่าเราสามารถสันนิษฐานได้ว่ารหัสนี้ใช้งานได้ง่าย (แทนที่จะเป็นรหัสที่อักขระใน ข้อมูลดั้งเดิมจะถูกเข้ารหัสจริง) หากคุณพยายามแสดงค่าที่ได้รับจะมีคำถามหรือ krakozyably บนหน้าจอ ตัวอย่างเช่น เมื่ออ่านสตริง "ABC" ในการเข้ารหัส Windows ข้อมูลเช่นนี้สามารถแสดงได้อย่างง่ายดาย: "АÁВ" โค้ดประเภทนี้มักเขียนโดยโปรแกรมเมอร์ในฝั่งตะวันตก ซึ่งใช้ได้กับตัวอักษรภาษาอังกฤษ ไม่เป็นไร การแก้ไขรหัสนี้เป็นเรื่องง่าย - คุณเพียงแค่ต้องแทนที่ StringBuffer ด้วย ByteArrayOutputStream:

InputStream คือ = ..; int ข; ByteArrayOutputStream baos = ใหม่ ByteArrayOutputStream (); ในขณะที่ ((b = is.read ())! = - 1) (baos.write (b);) // แปลงไบต์เป็นสตริงโดยใช้การเข้ารหัสเริ่มต้นสตริง s = baos.toString (); // หากคุณต้องการการเข้ารหัสเฉพาะ ให้ระบุเมื่อเรียกใช้ toString (): // // s = baos.toString ("Cp1251");
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับข้อผิดพลาดทั่วไป โปรดดูส่วน

การเข้ารหัสตัวอักษรรัสเซีย 8 บิต

นี่คือการเข้ารหัส 8 บิตหลักของตัวอักษรรัสเซียที่แพร่หลาย:

นอกจากชื่อหลักแล้ว คุณสามารถใช้คำพ้องความหมายได้ ชุดของพวกเขาอาจแตกต่างกันใน JDK เวอร์ชันต่างๆ นี่คือรายการจาก JDK 1.3.1:

  • CP1251:
    • Windows-1251
  • CP866:
    • IBM866
    • IBM-866
    • CP866
    • CSIBM866
  • KOI8_R:
    • KOI8-R
    • CSKOI8R
  • ISO8859_5:
    • ISO8859-5
    • ISO-8859-5
    • ISO_8859-5
    • ISO_8859-5: 1988
    • ISO-IR-144
    • 8859_5
    • ซิริลลิก
    • CSISOละตินCyrillic
    • IBM915
    • IBM-915
    • Cp915

นอกจากนี้ คำพ้องความหมาย ซึ่งแตกต่างจากชื่อหลัก ไม่คำนึงถึงตัวพิมพ์เล็ก-ใหญ่ ซึ่งเป็นคุณลักษณะของการนำไปใช้งาน

เป็นที่น่าสังเกตว่าการเข้ารหัสเหล่านี้อาจไม่พร้อมใช้งานใน JVM บางตัว ตัวอย่างเช่น คุณสามารถดาวน์โหลด JRE สองเวอร์ชันที่แตกต่างกันจากเว็บไซต์ Sun - US และ International ในเวอร์ชันสหรัฐอเมริกา มีเพียง ISO-8859-1, ASCII, Cp1252, UTF8, UTF16 และ Unicode แบบไบต์คู่หลายรูปแบบ อย่างอื่นมีเฉพาะในเวอร์ชันสากลเท่านั้น บางครั้งด้วยเหตุนี้ คุณจึงสามารถใช้คราดด้วยการเปิดตัวโปรแกรม แม้ว่าจะไม่ต้องการตัวอักษรรัสเซียก็ตาม ข้อผิดพลาดทั่วไปที่เกิดขึ้นขณะทำสิ่งนี้:

เกิดข้อผิดพลาดระหว่างการเริ่มต้น VM java / lang / ClassNotFoundException: sun / io / ByteToCharCp1251

มันเกิดขึ้นเนื่องจากเดาได้ไม่ยากเนื่องจาก JVM ตามการตั้งค่าภูมิภาคของรัสเซียพยายามตั้งค่าการเข้ารหัสเริ่มต้นใน Cp1251 แต่ตั้งแต่ คลาสของการสนับสนุนดังกล่าวไม่มีในเวอร์ชันสหรัฐอเมริกา

ไฟล์และสตรีมข้อมูล

เช่นเดียวกับไบต์ที่แยกตามแนวคิดจากอักขระ Java จะแยกความแตกต่างระหว่างสตรีมไบต์และสตรีมอักขระ การทำงานกับไบต์แสดงโดยคลาสที่สืบทอดคลาส InputStream หรือ OutputStream โดยตรงหรือโดยอ้อม (รวมถึงคลาส RandomAccessFile ที่ไม่ซ้ำกัน) การทำงานกับสัญลักษณ์นั้นแสดงโดยคลาส Reader / Writer อันแสนหวาน (และลูกหลานของพวกเขาแน่นอน)

สตรีมของไบต์ใช้เพื่ออ่าน / เขียนไบต์ที่ไม่ได้แปลง ถ้าคุณรู้ว่าไบต์แสดงเฉพาะอักขระในการเข้ารหัสบางอย่าง คุณสามารถใช้คลาสตัวแปลงพิเศษ InputStreamReader และ OutputStreamWriter เพื่อรับกระแสของอักขระและทำงานกับมันโดยตรง ซึ่งมักจะมีประโยชน์สำหรับไฟล์ข้อความธรรมดาหรือเมื่อทำงานกับโปรโตคอลเครือข่ายของอินเทอร์เน็ตจำนวนมาก ในกรณีนี้ การเข้ารหัสอักขระถูกระบุในตัวสร้างของคลาสตัวแปลง ตัวอย่าง:

// สตริง Unicode สตริงสตริง = "..."; // เขียนสตริงลงในไฟล์ข้อความในการเข้ารหัส Cp866 PrintWriter pw = PrintWriter ใหม่ // คลาสพร้อมเมธอดสำหรับเขียนสตริง(ใหม่ OutputStreamWriter // คลาสตัวแปลง(FileOutputStream ใหม่ ("file.txt"), "Cp866"); pw.println (สตริง); // เขียนบรรทัดไปที่ไฟล์ pw.close ();

หากสตรีมอาจมีข้อมูลในการเข้ารหัสที่แตกต่างกัน หรืออักขระผสมกับข้อมูลไบนารีอื่น ๆ จะเป็นการดีกว่าที่จะอ่านและเขียนไบต์อาร์เรย์ (ไบต์) และใช้วิธีการที่กล่าวถึงแล้วของคลาส String สำหรับการแปลง ตัวอย่าง:

// สตริง Unicode สตริงสตริง = "..."; // เขียนสตริงลงในไฟล์ข้อความด้วยการเข้ารหัสสองแบบ (Cp866 และ Cp1251)ระบบปฏิบัติการ OutputStream = FileOutputStream ใหม่ ("file.txt"); // class สำหรับเขียนไบต์ลง file // เขียนสตริงในการเข้ารหัส Cp866 os.write (string.getBytes ("Cp866")); // เขียนสตริงในการเข้ารหัส Cp1251 os.write (string.getBytes ("Cp1251")); os.close ();

คอนโซลใน Java มักจะแสดงโดยสตรีม แต่น่าเสียดายที่ไม่ใช่อักขระ แต่เป็นไบต์ ความจริงก็คือกระแสอักขระปรากฏใน JDK 1.1 เท่านั้น (พร้อมกับกลไกการเข้ารหัสทั้งหมด) และการเข้าถึงคอนโซล I / O ได้รับการออกแบบใน JDK 1.0 ซึ่งนำไปสู่การปรากฏตัวของประหลาดในรูปแบบของคลาส PrintStream คลาสนี้ใช้ในตัวแปร System.out และ System.err ซึ่งให้การเข้าถึงเอาต์พุตไปยังคอนโซล ตามบัญชีทั้งหมด นี่เป็นสตรีมของไบต์ แต่มีวิธีการมากมายในการเขียนสตริง เมื่อคุณเขียนสตริงลงไป มันจะแปลงเป็นไบต์โดยใช้การเข้ารหัสเริ่มต้น ซึ่งมักจะไม่ยอมรับในกรณีของ Windows - การเข้ารหัสเริ่มต้นจะเป็น Cp1251 (Ansi) และสำหรับหน้าต่างคอนโซล คุณมักจะต้องใช้ Cp866 ( OEM). ข้อผิดพลาดนี้ได้รับการบันทึกในปีที่ 97 () แต่ดูเหมือนว่า Sun-sheep จะไม่รีบแก้ไข เนื่องจากไม่มีวิธีการตั้งค่าการเข้ารหัสใน PrintStream เพื่อแก้ปัญหานี้ คุณสามารถแทนที่คลาสมาตรฐานด้วยคลาสของคุณเองโดยใช้วิธี System.setOut () และ System.setErr () ตัวอย่างเช่น นี่เป็นการเริ่มต้นตามปกติในโปรแกรมของฉัน:

... public static void main (สตริง args) ( // ตั้งค่าเอาต์พุตของข้อความคอนโซลในการเข้ารหัสที่ต้องการลอง (สตริง consoleEnc = System.getProperty ("console.encoding", "Cp866"); System.setOut (CodepagePrintStream ใหม่ (System.out, consoleEnc)); System.setErr (CodepagePrintStream ใหม่ (System.err, consoleEnc)); ) จับ (UnsupportedEncodingException e) (System.out.println ("ไม่สามารถตั้งค่าหน้ารหัสคอนโซล:" + e);) ...

คุณสามารถค้นหาแหล่งที่มาของคลาส CodepagePrintStream บนเว็บไซต์นี้: CodepagePrintStream.java

หากคุณกำลังสร้างรูปแบบข้อมูลด้วยตนเอง เราขอแนะนำให้คุณใช้การเข้ารหัสแบบหลายไบต์ตัวใดตัวหนึ่ง รูปแบบที่สะดวกที่สุดมักจะเป็น UTF8 - 128 ค่าแรก (ASCII) ในนั้นจะถูกเข้ารหัสในหนึ่งไบต์ซึ่งมักจะลดจำนวนข้อมูลทั้งหมดได้อย่างมาก (ไม่ใช่เพื่ออะไรที่การเข้ารหัสนี้เป็นพื้นฐานใน โลก XML) แต่ UTF8 มีข้อเสียอยู่อย่างหนึ่ง - จำนวนไบต์ที่ต้องการขึ้นอยู่กับรหัสอักขระ ในกรณีที่มีความสำคัญ คุณสามารถใช้รูปแบบ Unicode แบบสองไบต์ (UnicodeBig หรือ UnicodeLittle) ได้

ฐานข้อมูล

เพื่อที่จะอ่านอักขระจากฐานข้อมูลอย่างถูกต้อง มักจะเพียงพอที่จะบอกไดรเวอร์ JDBC ถึงการเข้ารหัสอักขระที่จำเป็นในฐานข้อมูล ขึ้นอยู่กับไดรเวอร์เฉพาะอย่างไร ทุกวันนี้ ไดรเวอร์จำนวนมากรองรับการตั้งค่านี้แล้ว ตรงกันข้ามกับเมื่อเร็วๆ นี้ นี่คือตัวอย่างบางส่วนที่ฉันรู้

สะพาน JDBC-ODBC

นี่เป็นหนึ่งในไดรเวอร์ที่ใช้บ่อยที่สุด บริดจ์จาก JDK 1.2 และเก่ากว่าสามารถกำหนดค่าได้อย่างง่ายดายเพื่อเข้ารหัสที่ต้องการ ทำได้โดยการเพิ่มคุณสมบัติ charSet เพิ่มเติมให้กับชุดของพารามิเตอร์ที่ส่งผ่านเพื่อเปิดการเชื่อมต่อกับฐาน ค่าดีฟอลต์คือ file.encoding สิ่งนี้ทำสิ่งนี้:

// สร้างการเชื่อมต่อ

ไดรเวอร์ Oracle 8.0.5 JDBC-OCI สำหรับ Linux

เมื่อได้รับข้อมูลจากฐานข้อมูล ไดรเวอร์นี้จะกำหนดการเข้ารหัส "ของมัน" โดยใช้ตัวแปรสภาพแวดล้อม NLS_LANG หากไม่พบตัวแปรนี้ จะถือว่าการเข้ารหัสเป็น ISO-8859-1 เคล็ดลับคือ NLS_LANG ควรเป็นตัวแปรสภาพแวดล้อม (ตั้งค่าด้วยคำสั่ง set) ไม่ใช่คุณสมบัติของระบบ Java (เช่น file.encoding) หากใช้ไดรเวอร์ภายในเอ็นจินเซิร์ฟเล็ต Apache + Jserv ตัวแปรสภาพแวดล้อมสามารถตั้งค่าได้ในไฟล์ jserv.properties:

wrapper.env = NLS_LANG = American_America.CL8KOI8R
ข้อมูลเกี่ยวกับสิ่งนี้ถูกส่งโดย Sergey Bezrukov ซึ่งต้องขอบคุณเขาเป็นพิเศษ

ไดรเวอร์ JDBC สำหรับการทำงานกับ DBF (zyh.sql.dbf.DBFDriver)

คนขับคนนี้เพิ่งเรียนรู้ที่จะทำงานกับตัวอักษรรัสเซีย แม้ว่าเขาจะรายงานโดย getPropertyInfo () ว่าเขาเข้าใจคุณสมบัติ charSet แต่ก็เป็นนิยาย (อย่างน้อยก็ในเวอร์ชันตั้งแต่ 30/07/2544) ในความเป็นจริง คุณสามารถปรับแต่งการเข้ารหัสโดยการตั้งค่าคุณสมบัติ CODEPAGEID สำหรับอักขระรัสเซีย มีสองค่า - "66" สำหรับ Cp866 และ "C9" สำหรับ Cp1251 ตัวอย่าง:

// พารามิเตอร์การเชื่อมต่อกับฐานคุณสมบัติ connInfo = คุณสมบัติใหม่ (); connInfo.put ("CODEPAGEID", "66"); // การเข้ารหัส Cp866 // สร้างการเชื่อมต่อฐานข้อมูลการเชื่อมต่อ = DriverManager.getConnection ("jdbc: DBF: / C: / MyDBFFiles", connInfo);
หากคุณมีไฟล์ DBF ในรูปแบบ FoxPro ไฟล์เหล่านั้นจะมีข้อมูลเฉพาะของตนเอง ความจริงก็คือ FoxPro จะบันทึก ID ของหน้ารหัสในส่วนหัวของไฟล์ (ไบต์ที่มีออฟเซ็ต 0x1D) ซึ่งใช้ในการสร้าง DBF เมื่อเปิดตาราง ไดรเวอร์จะใช้ค่าจากส่วนหัว ไม่ใช่พารามิเตอร์ "CODEPAGEID" (พารามิเตอร์ในกรณีนี้จะใช้เมื่อสร้างตารางใหม่เท่านั้น) ดังนั้น เพื่อให้ทุกอย่างทำงานได้อย่างถูกต้อง ไฟล์ DBF จะต้องสร้างด้วยการเข้ารหัสที่ถูกต้อง ไม่เช่นนั้นจะเกิดปัญหาขึ้น

MySQL (org.gjt.mm.mysql.Driver)

ด้วยไดรเวอร์นี้ ทุกอย่างก็ค่อนข้างง่ายเช่นกัน:

// พารามิเตอร์การเชื่อมต่อกับฐานคุณสมบัติ connInfo = Poperties ใหม่ (); connInfo.put ("ผู้ใช้" ผู้ใช้); connInfo.put ("รหัสผ่าน", ผ่าน); connInfo.put ("useUnicode", "จริง"); connInfo.put ("การเข้ารหัสอักขระ", "KOI8_R"); การเชื่อมต่อ conn = DriverManager.getConnection (dbURL, อุปกรณ์ประกอบฉาก);

InterBase (interbase.interclient.Driver)

สำหรับไดรเวอร์นี้ พารามิเตอร์ "charSet" ใช้งานได้:
// พารามิเตอร์การเชื่อมต่อกับฐานคุณสมบัติ connInfo = คุณสมบัติใหม่ (); connInfo.put ("ผู้ใช้", ชื่อผู้ใช้); connInfo.put ("รหัสผ่าน", รหัสผ่าน); connInfo.put ("charSet", "Cp1251"); // สร้างการเชื่อมต่อฐานข้อมูลการเชื่อมต่อ = DriverManager.getConnection (dataurl, connInfo);

อย่างไรก็ตาม อย่าลืมระบุการเข้ารหัสอักขระเมื่อสร้างฐานข้อมูลและตาราง สำหรับภาษารัสเซีย คุณสามารถใช้ค่า "UNICODE_FSS" หรือ "WIN1251" ตัวอย่าง:

สร้างฐานข้อมูล "E: \ ProjectHolding \ DataBase \ HOLDING.GDB" PAGE_SIZE 4096 ชุดอักขระเริ่มต้น UNICODE_FSS; สร้างตาราง RUSSIAN_WORD ("NAME1" VARCHAR (40) ชุดอักขระ UNICODE_FSS ไม่ใช่ NULL "NAME2" VARCHAR (40) ชุดอักขระ WIN1251 ไม่ใช่ NULL คีย์หลัก ("NAME1"));

มีข้อบกพร่องในเวอร์ชัน 2.01 ของ InterClient - คลาสทรัพยากรที่มีข้อความสำหรับภาษารัสเซียไม่ได้รับการคอมไพล์อย่างถูกต้อง เป็นไปได้มากที่นักพัฒนาจะลืมระบุการเข้ารหัสต้นทางเมื่อทำการคอมไพล์ มีสองวิธีในการแก้ไขข้อผิดพลาดนี้:

  • ใช้ interclient-core.jar แทน interclient.jar ในเวลาเดียวกันจะไม่มีแหล่งข้อมูลภาษารัสเซียและทรัพยากรภาษาอังกฤษจะถูกหยิบขึ้นมาโดยอัตโนมัติ
  • คอมไพล์ไฟล์ใหม่เป็น Unicode ปกติ การแยกวิเคราะห์ไฟล์คลาสเป็นงานที่ไม่เห็นคุณค่า ดังนั้นจึงควรใช้ JAD น่าเสียดายที่ JAD หากพบอักขระจากชุด ISO-8859-1 จะแสดงผลเป็นการเข้ารหัส 8 หลัก ดังนั้นคุณจะไม่สามารถใช้ตัวเข้ารหัส native2ascii มาตรฐานได้ - คุณต้องเขียนเอง (โปรแกรมถอดรหัส) หากคุณไม่ต้องการกังวลกับปัญหาเหล่านี้ คุณสามารถใช้ไฟล์สำเร็จรูปที่มีทรัพยากร (jar ที่แพทช์พร้อมไดรเวอร์ - interclient.jar แยกคลาสของทรัพยากร - interclient-rus.jar)

แต่ถึงแม้จะปรับไดรเวอร์ JDBC เป็นการเข้ารหัสที่ต้องการแล้ว ในบางกรณี คุณอาจประสบปัญหาได้ ตัวอย่างเช่น เมื่อพยายามใช้เคอร์เซอร์เลื่อน JDBC 2 ใหม่ที่ยอดเยี่ยมในบริดจ์ JDBC-ODBC จาก JDK 1.3.x คุณจะพบว่าตัวอักษรรัสเซียใช้งานไม่ได้ที่นั่น (เมธอด updateString ())

มีเรื่องเล็ก ๆ ที่เกี่ยวข้องกับข้อผิดพลาดนี้ เมื่อฉันค้นพบมันเป็นครั้งแรก (ภายใต้ JDK 1.3 rc2) ฉันลงทะเบียนกับ BugParade () เมื่อเบต้าแรกของ JDK 1.3.1 ออกมา จุดบกพร่องนี้ถูกตั้งค่าสถานะว่าได้รับการแก้ไขแล้ว ฉันดาวน์โหลดเบต้านี้แล้ว ทดสอบแล้ว - มันใช้งานไม่ได้ ฉันเขียนถึง Sun-sheep เกี่ยวกับเรื่องนี้ - ในการตอบกลับพวกเขาเขียนถึงฉันว่าการแก้ไขจะรวมอยู่ในรุ่นต่อๆ ไป โอเค ฉันคิดว่ารอก่อน เวลาผ่านไป รีลีส 1.3.1 ออกแล้ว และเบต้า 1.4 ในที่สุดฉันก็ใช้เวลาในการตรวจสอบ - มันใช้งานไม่ได้อีกครั้ง แม่ แม่ แม่ ... - เสียงสะท้อนก้องเป็นนิสัย หลังจากจดหมายโกรธถึง Sun พวกเขาแนะนำข้อผิดพลาดใหม่ () ซึ่งพวกเขามอบให้กับสาขาของอินเดียเพื่อแยกส่วน ชาวอินเดียเล่นซอกับรหัสและกล่าวว่าทุกอย่างได้รับการแก้ไขใน 1.4 beta3 ฉันดาวน์โหลดเวอร์ชันนี้ ใช้กรณีทดสอบภายใต้เวอร์ชันนี้ นี่คือผลลัพธ์ - ตามที่ปรากฏ beta3 ที่เผยแพร่บนไซต์ (รุ่น 84) ไม่ใช่ beta3 ที่มีการแก้ไขขั้นสุดท้าย (รุ่น 87) ตอนนี้พวกเขาสัญญาว่าการแก้ไขจะรวมอยู่ใน 1.4 rc1 ... โดยทั่วไปแล้วคุณเข้าใจ :-)

ตัวอักษรรัสเซียในแหล่งที่มาของโปรแกรม Java

ดังที่กล่าวไว้ โปรแกรมใช้ Unicode เมื่อดำเนินการ ไฟล์ต้นฉบับเขียนด้วยโปรแกรมแก้ไขทั่วไป ฉันใช้ Far คุณอาจจะมีบรรณาธิการที่คุณชื่นชอบ โปรแกรมแก้ไขเหล่านี้บันทึกไฟล์ในรูปแบบ 8 บิต ซึ่งหมายความว่าการใช้เหตุผลแบบเดียวกับข้างต้นจะมีผลกับไฟล์เหล่านี้เช่นกัน คอมไพเลอร์รุ่นต่างๆ ทำการแปลงอักขระแตกต่างกันเล็กน้อย JDK 1.1.x เวอร์ชันก่อนหน้าใช้การตั้งค่า file.encoding ซึ่งสามารถแทนที่ด้วยตัวเลือก -J ที่ไม่ได้มาตรฐาน ในเวอร์ชันที่ใหม่กว่า (ตามที่รายงานโดย Denis Kokarev - เริ่มตั้งแต่ 1.1.4) มีการแนะนำพารามิเตอร์ -encoding เพิ่มเติมซึ่งคุณสามารถระบุการเข้ารหัสที่ใช้ได้ ในคลาสที่คอมไพล์ สตริงจะแสดงในรูปแบบของ Unicode (แม่นยำกว่านั้น ในรูปแบบ UTF8) ที่แก้ไขแล้ว ดังนั้นสิ่งที่น่าสนใจที่สุดจึงเกิดขึ้นระหว่างการคอมไพล์ ดังนั้น สิ่งที่สำคัญที่สุดคือการค้นหาสิ่งที่เข้ารหัสซอร์สโค้ดของคุณ และระบุค่าที่ถูกต้องเมื่อทำการคอมไพล์ โดยค่าเริ่มต้น file.encoding ที่มีชื่อเสียงเหมือนกันจะถูกใช้ ตัวอย่างของการเรียกคอมไพเลอร์:

นอกจากการใช้การตั้งค่านี้แล้ว ยังมีอีกวิธีหนึ่งคือ - เพื่อระบุตัวอักษรในรูปแบบ "\ uXXXX" ซึ่งระบุรหัสอักขระ วิธีนี้ใช้ได้กับทุกเวอร์ชัน และคุณสามารถใช้ยูทิลิตี้มาตรฐานเพื่อรับโค้ดเหล่านี้ได้

หากคุณใช้ IDE ใด ๆ แสดงว่าอาจมีข้อบกพร่องของตัวเอง บ่อยครั้งที่ IDE เหล่านี้ใช้การเข้ารหัสเริ่มต้นสำหรับการอ่าน / บันทึกแหล่งที่มา ดังนั้นให้ใส่ใจกับการตั้งค่าภูมิภาคของระบบปฏิบัติการของคุณ นอกจากนี้ อาจมีข้อผิดพลาดที่ชัดเจน ตัวอย่างเช่น CodeGuide ระดับ IDE ที่ค่อนข้างดีไม่สามารถแยกแยะตัวอักษรรัสเซียตัวพิมพ์ใหญ่ "T" ได้ ตัววิเคราะห์โค้ดในตัวใช้จดหมายนี้เป็นเครื่องหมายอัญประกาศคู่ ซึ่งนำไปสู่ความจริงที่ว่าโค้ดที่ถูกต้องถูกมองว่าผิดพลาด คุณสามารถต่อสู้กับสิ่งนี้ (โดยแทนที่ตัวอักษร "T" ด้วยรหัส "\ u0422") แต่ไม่น่าพอใจ เห็นได้ชัดว่าบางแห่งใน parser มีการแปลงอักขระอย่างชัดเจนเป็นไบต์ (เช่น: byte b = (byte) c) ดังนั้นแทนที่จะใช้รหัส 0x0422 (รหัสของตัวอักษร "T") รหัสคือ 0x22 ( รหัสของอัญประกาศคู่)

JBuilder มีปัญหาอื่น แต่เกี่ยวข้องกับการยศาสตร์มากกว่า ความจริงก็คือใน JDK 1.3.0 ซึ่ง JBuilder ทำงานโดยค่าเริ่มต้น มีข้อบกพร่อง () เนื่องจากหน้าต่าง GUI ที่สร้างขึ้นใหม่เมื่อเปิดใช้งานจะรวมเค้าโครงแป้นพิมพ์โดยอัตโนมัติขึ้นอยู่กับการตั้งค่าภูมิภาคของระบบปฏิบัติการ เหล่านั้น. หากคุณมีการตั้งค่าภูมิภาคของรัสเซีย จะพยายามเปลี่ยนไปใช้เค้าโครงภาษารัสเซียอย่างต่อเนื่อง ซึ่งจะขัดขวางการเขียนโปรแกรม ไซต์ JBuilder.ru มีแพตช์สองสามตัวที่เปลี่ยนสถานที่ปัจจุบันใน JVM เป็น Locale.US แต่วิธีที่ดีที่สุดคือการอัปเกรดเป็น JDK 1.3.1 ซึ่งได้แก้ไขข้อผิดพลาดนี้แล้ว

ผู้ใช้ JBuilder มือใหม่อาจประสบปัญหาดังกล่าว - ตัวอักษรรัสเซียจะถูกบันทึกเป็นรหัส "\ uXXXX" เพื่อหลีกเลี่ยงปัญหานี้ ในกล่องโต้ตอบคุณสมบัติโปรเจ็กต์เริ่มต้น แท็บทั่วไป ในฟิลด์การเข้ารหัส ให้เปลี่ยนค่าเริ่มต้นเป็น Cp1251

หากคุณกำลังใช้สำหรับการคอมไพล์ไม่ใช่จาวามาตรฐาน แต่เป็นคอมไพเลอร์ตัวอื่น - ให้ความสนใจกับวิธีการแปลงอักขระ ตัวอย่างเช่น คอมไพเลอร์ IBM jikes บางเวอร์ชันไม่เข้าใจว่ามีการเข้ารหัสอื่นที่ไม่ใช่ ISO-8859-1 :-) มีเวอร์ชันที่ได้รับการแก้ไขในเรื่องนี้ แต่บ่อยครั้งที่การเข้ารหัสบางส่วนถูกเย็บไว้ที่นั่นด้วย - ไม่มีความสะดวกเช่นใน javac

JavaDoc

ในการสร้างเอกสาร HTML สำหรับซอร์สโค้ด จะใช้ยูทิลิตี้ javadoc ซึ่งรวมอยู่ในการแจกจ่าย JDK มาตรฐาน ในการระบุการเข้ารหัส มีพารามิเตอร์มากถึง 3 ตัว:

  • -encoding - การตั้งค่านี้ระบุการเข้ารหัสต้นทาง ค่าดีฟอลต์คือ file.encoding
  • -docencoding - การตั้งค่านี้ระบุการเข้ารหัสของไฟล์ HTML ที่สร้างขึ้น ค่าดีฟอลต์คือ file.encoding
  • -charset - การตั้งค่านี้ระบุการเข้ารหัสที่จะเขียนไปยังส่วนหัวของไฟล์ HTML ที่สร้างขึ้น ( ). เห็นได้ชัดว่ามันควรจะเหมือนกับการตั้งค่าก่อนหน้านี้ หากละเว้นการตั้งค่านี้ เมตาแท็กจะไม่ถูกเพิ่ม

ตัวอักษรรัสเซียในไฟล์คุณสมบัติ

วิธีการโหลดทรัพยากรใช้เพื่ออ่านไฟล์คุณสมบัติ ซึ่งทำงานในลักษณะเฉพาะ ที่จริงแล้ว วิธี Properties.load ใช้สำหรับการอ่าน ซึ่งไม่ได้ใช้ file.encoding (ซอร์สโค้ดถูกฮาร์ดโค้ดด้วยการเข้ารหัส ISO-8859-1) ดังนั้นวิธีเดียวที่จะระบุตัวอักษรรัสเซียคือการใช้ "\ uXXXX" รูปแบบและยูทิลิตี้

วิธีการ Properties.save ทำงานแตกต่างกันใน JDK 1.1 และ 1.2 ในเวอร์ชัน 1.1 มันเพียงแค่ทิ้ง high byte ดังนั้นมันจึงทำงานอย่างถูกต้องกับตัวอักษรภาษาอังกฤษเท่านั้น 1.2 ทำการแปลงย้อนกลับเป็น "\ uXXXX" ดังนั้นจึงทำงานเหมือนวิธีการโหลด

หากไฟล์คุณสมบัติของคุณไม่ได้โหลดเป็นรีซอร์ส แต่เป็นไฟล์คอนฟิกูเรชันทั่วไป และคุณไม่พอใจกับพฤติกรรมนี้ มีทางเดียวเท่านั้นคือเขียนตัวโหลดของคุณเอง

ตัวอักษรรัสเซียใน Servlets

ฉันคิดว่า Servlets เดียวกันนี้มีไว้เพื่ออะไร ฉันคิดว่าคุณรู้ ถ้าไม่ ทางที่ดีควรอ่านเอกสารก่อน ที่นี่อธิบายลักษณะเฉพาะของการทำงานกับตัวอักษรรัสเซียเท่านั้น

แล้วคุณสมบัติมีอะไรบ้าง? เมื่อ Servlet ส่งการตอบกลับไปยังไคลเอนต์ มีสองวิธีในการส่งการตอบสนองนั้น — ผ่านวิธี OutputStream (getOutputStream ()) หรือวิธี PrintWriter (getWriter ()) ในกรณีแรก คุณกำลังเขียนอาร์เรย์ของไบต์ ดังนั้นวิธีการข้างต้นในการเขียนไปยังสตรีมจึงมีผลบังคับใช้ ในกรณีของ PrintWriter จะใช้ชุดการเข้ารหัส ไม่ว่าในกรณีใด คุณต้องระบุการเข้ารหัสที่ใช้เมื่อเรียกใช้เมธอด setContentType () อย่างถูกต้อง เพื่อให้สามารถแปลงอักขระในฝั่งเซิร์ฟเวอร์ได้ถูกต้อง คำสั่งนี้ต้องทำก่อนการเรียก getWriter () หรือก่อนการเขียนครั้งแรกไปยัง OutputStream ตัวอย่าง:

// ตั้งค่าการเข้ารหัสของการตอบสนอง // โปรดทราบว่าเอ็นจิ้นบางตัวไม่อนุญาต // ช่องว่างระหว่าง ";" และ "ชุดอักขระ" response.setContentType ("ข้อความ / html; ชุดอักขระ = UTF-8"); PrintWriter out = response.getWriter (); // ดีบักเอาต์พุตของชื่อการเข้ารหัสที่จะตรวจสอบ out.println ("การเข้ารหัส:" + response.getCharacterEncoding ()); ... out.close (); )

คือการให้คำตอบกับลูกค้า น่าเสียดายที่พารามิเตอร์อินพุตไม่ง่ายนัก พารามิเตอร์อินพุตถูกเข้ารหัสโดยไบต์ของเบราว์เซอร์ตามประเภท MIME "application / x-www-form-urlencoded" ตามที่ Alexey Mendelev กล่าว เบราว์เซอร์เข้ารหัสตัวอักษรรัสเซียโดยใช้การเข้ารหัสที่ตั้งไว้ในปัจจุบัน และแน่นอนว่าไม่มีรายงานเกี่ยวกับเรื่องนี้ ตัวอย่างเช่น ในเวอร์ชัน JSDK ตั้งแต่ 2.0 ถึง 2.2 สิ่งนี้จะไม่ถูกตรวจสอบ แต่อย่างใด และการเข้ารหัสประเภทใดที่จะใช้สำหรับการแปลงขึ้นอยู่กับเอ็นจิ้นที่ใช้ เริ่มต้นด้วยข้อกำหนด 2.3 เป็นไปได้ที่จะตั้งค่าการเข้ารหัสสำหรับ javax.servlet.ServletRequest - เมธอด setCharacterEncoding () Resin และ Tomcat เวอร์ชันล่าสุดรองรับข้อกำหนดนี้แล้ว

ดังนั้น หากคุณโชคดีและคุณมีเซิร์ฟเวอร์ที่รองรับ Servlet 2.3 ทุกอย่างก็ค่อนข้างง่าย:

doPost โมฆะสาธารณะ (คำขอ HttpServletRequest การตอบสนอง HttpServletResponse) พ่น ServletException, IOException ( // การเข้ารหัสข้อความ request.setCharacterEncoding ("Cp1251"); ค่าสตริง = request.getParameter ("ค่า"); ...

มีความละเอียดอ่อนที่สำคัญอย่างหนึ่งในการใช้เมธอด request.setCharacterEncoding () - ต้องใช้ ก่อนการเรียกขอข้อมูลครั้งแรก (เช่น request.getParameter ()) หากคุณใช้ตัวกรองที่ประมวลผลคำขอก่อนที่จะมาถึงเซิร์ฟเล็ต มีโอกาสไม่ใช่ศูนย์ที่ตัวกรองตัวใดตัวหนึ่งอาจอ่านพารามิเตอร์บางตัวจากคำขอ (เช่น สำหรับการอนุญาต) และ request.setCharacterEncoding () ในเซิร์ฟเล็ตจะไม่ ทำงาน ...

ดังนั้นจึงถูกต้องตามหลักอุดมคติมากกว่าที่จะเขียนตัวกรองที่กำหนดการเข้ารหัสคำขอ ยิ่งไปกว่านั้น จะต้องเป็นลำดับแรกในกลุ่มตัวกรองใน web.xml

ตัวอย่างของตัวกรองดังกล่าว:

นำเข้า java.io *; นำเข้า java.util *; นำเข้า javax.servlet. *; นำเข้า javax.servlet.http. *; CharsetFilter คลาสสาธารณะใช้ตัวกรอง (// การเข้ารหัสการเข้ารหัสสตริงส่วนตัว init โมฆะสาธารณะ (การกำหนดค่า FilterConfig) พ่น ServletException ( // อ่านจาก configการเข้ารหัส = config.getInitParameter ("requestEncoding"); // ถ้าไม่ได้ติดตั้ง ให้ติดตั้ง Cp1251ถ้า (การเข้ารหัส == null) การเข้ารหัส = "Cp1251"; ) โมฆะสาธารณะ doFilter (คำขอ ServletRequest, การตอบสนอง ServletResponse, FilterChain ถัดไป) พ่น IOException, ServletException (request.setCharacterEncoding (การเข้ารหัส); next.doFilter (คำขอ, การตอบสนอง);) การทำลายโมฆะสาธารณะ () ())

และการกำหนดค่าใน web.xml:

ตัวกรองชุดอักขระ CharsetFilter ตัวกรองชุดอักขระ /*

หากคุณโชคร้ายและคุณมีมากขึ้น เวอร์ชั่นเก่า- เพื่อให้ได้ผลลัพธ์ คุณจะต้องบิดเบือน:

    Russian Apache นำเสนอวิธีดั้งเดิมในการทำงานกับการเข้ารหัส - มีการอธิบายอย่างชัดเจนว่าเป็นอย่างไร

  • FOP

    หากโปรแกรมไม่ทำงานทุกที่แสดงว่าปัญหาอยู่ในมือคุณเท่านั้น อ่านทุกอย่างที่เขียนไว้ด้านบนอย่างรอบคอบแล้วดู หากปัญหาปรากฏเฉพาะในสภาพแวดล้อมเฉพาะ แสดงว่าปัญหาอาจอยู่ในการตั้งค่า ขึ้นอยู่กับไลบรารีกราฟิกที่คุณใช้อยู่ ถ้า AWT - การกำหนดค่าที่ถูกต้องของไฟล์ font.properties.ru สามารถช่วยได้ ตัวอย่างของไฟล์ที่ถูกต้องสามารถนำมาจาก Java 2 ได้ หากคุณไม่มีเวอร์ชันนี้ คุณสามารถดาวน์โหลดได้จากเว็บไซต์นี้: เวอร์ชัน Windows, เวอร์ชัน Linux (ดูด้านล่าง) ไฟล์นี้ระบุฟอนต์และโค้ดเพจที่จะใช้ หากคุณติดตั้งระบบปฏิบัติการเวอร์ชันรัสเซีย เพียงเพิ่มไฟล์นี้ลงในตำแหน่งที่ไฟล์ font.properties ตั้งอยู่ หากเป็นเวอร์ชันภาษาอังกฤษ คุณต้องเขียนไฟล์นี้ใหม่แทน font.properties หรือเปลี่ยนการตั้งค่าภูมิภาคปัจจุบันเป็นภาษารัสเซียเพิ่มเติม บางครั้งการตั้งค่า -Duser.language = ru อาจใช้งานได้ แต่บ่อยครั้งก็ไม่เป็นเช่นนั้น มีปัญหาเดียวกันกับ file.encoding - ไม่ว่าจะทำงานหรือไม่ขึ้นอยู่กับ JDK (ดูข้อผิดพลาดตามตัวเลข)

    ด้วยไลบรารี Swing ทุกอย่างจะง่ายขึ้น - ทุกอย่างในนั้นถูกดึงผ่านระบบย่อย Java2D การแปลงป้ายกำกับในกล่องโต้ตอบมาตรฐาน (JOptionPane, JFileChooser, JColorChooser) เป็นภาษารัสเซียทำได้ง่ายมาก คุณเพียงแค่ต้องสร้างไฟล์ทรัพยากรหลายไฟล์ ฉันได้ทำสิ่งนี้ไปแล้ว ดังนั้นคุณจึงสามารถนำไฟล์ที่เสร็จแล้วมาเพิ่มใน lib \ ext หรือ CLASSPATH ได้ ปัญหาเดียวที่ฉันพบคือในเวอร์ชัน JDK ที่เริ่มต้นจาก 1.2 rc1 และ 1.3 เบต้า ตัวอักษรรัสเซียจะไม่แสดงภายใต้ Win9x เมื่อใช้แบบอักษรมาตรฐาน (Arial, Courier New, Times New Roman เป็นต้น) เนื่องจากข้อบกพร่องใน Java2D ข้อผิดพลาดค่อนข้างแปลก - ด้วยแบบอักษรมาตรฐาน รูปภาพตัวอักษรจะไม่แสดงตามรหัส Unicode แต่ตามตาราง Cp1251 ( การเข้ารหัส Ansi). จุดบกพร่องนี้มีการลงทะเบียนใน BugParade ภายใต้หมายเลข ตามค่าเริ่มต้น Swing จะใช้แบบอักษรที่ระบุในไฟล์ font.properties.ru ดังนั้นจึงเพียงพอที่จะแทนที่ด้วยแบบอักษรอื่นและตัวอักษรรัสเซียจะปรากฏขึ้น น่าเสียดายที่ชุดฟอนต์ทำงานมีขนาดเล็ก - เหล่านี้คือฟอนต์ Tahoma, Tahoma Bold และฟอนต์สองชุดจากการแจกจ่าย JDK - Lucida Sans * และเครื่องพิมพ์ดีด Lucida * (ตัวอย่างของไฟล์ font.properties.ru) แบบอักษรเหล่านี้แตกต่างจากแบบอักษรมาตรฐานอย่างไรไม่ชัดเจนสำหรับฉัน

    ตั้งแต่เวอร์ชัน 1.3rc1 ปัญหานี้ได้รับการแก้ไขแล้ว ดังนั้นคุณเพียงแค่ต้องอัปเดต JDK JDK 1.2 นั้นล้าสมัยไปแล้ว ดังนั้นฉันจึงไม่แนะนำให้ใช้ ควรสังเกตด้วยว่า Win95 เวอร์ชันดั้งเดิมมาพร้อมกับฟอนต์ที่ไม่รองรับ Unicode - ในสถานการณ์นี้ คุณสามารถคัดลอกฟอนต์จาก Win98 หรือ WinNT ได้ง่ายๆ

    ข้อผิดพลาดทั่วไปหรือ "ตัวอักษร W หายไปไหน"

    จดหมาย Sh.

    คำถามนี้ ("ตัวอักษร W หายไปไหน") มักถูกถามโดยโปรแกรมเมอร์ Java มือใหม่ เรามาดูกันว่ามันไปที่ไหนบ่อยที่สุด :-)

    นี่คือโปรแกรมสไตล์ HelloWorld ทั่วไป:

    การทดสอบคลาสสาธารณะ (โมฆะคงที่สาธารณะหลัก (สตริง args) (System.out.println ("ИЦУКЕНГШЩЗХЪ");))
    ใน Far บันทึกรหัสนี้ลงในไฟล์ Test.java รวบรวม ...
    C: \> javac Test.java
    และวิ่ง ...
    C: \> ทดสอบจาวา YTsUKENG? ЩЗХЪ

    เกิดอะไรขึ้น? ตัวอักษร W หายไปไหน? เคล็ดลับคือมีการชดเชยข้อผิดพลาดสองข้อร่วมกัน โปรแกรมแก้ไขข้อความของ Far สร้างไฟล์ที่เข้ารหัส DOS (Cp866) โดยค่าเริ่มต้น คอมไพเลอร์ javac ใช้ file.encoding เพื่ออ่านซอร์ส (เว้นแต่จะระบุไว้เป็นอย่างอื่นด้วยคีย์ -encoding) และใน สภาพแวดล้อมของ Windowsด้วยภาษารัสเซียการเข้ารหัสเริ่มต้นคือ Cp1251 นี่เป็นความผิดพลาดครั้งแรก ด้วยเหตุนี้ สัญลักษณ์ในไฟล์ Test.class ที่คอมไพล์แล้วจึงมีรหัสที่ไม่ถูกต้อง ข้อผิดพลาดที่สองคือ PrintStream มาตรฐานใช้สำหรับเอาต์พุต ซึ่งใช้การตั้งค่าจาก file.encoding ด้วย แต่หน้าต่างคอนโซล Windows จะแสดงอักขระโดยใช้การเข้ารหัส DOS หากการเข้ารหัส Cp1251 ใช้ร่วมกันได้ ข้อมูลจะไม่สูญหาย แต่อักขระ W ใน Cp866 มีรหัส 152 ซึ่งไม่ได้กำหนดไว้ใน Cp1251 ดังนั้นจึงแมปกับอักขระ Unicode 0xFFFD เมื่อแปลงกลับจากถ่านเป็นไบต์ "?" จะถูกแทนที่ด้วย

    คุณสามารถใช้การชดเชยที่คล้ายกันได้หากคุณอ่านอักขระจากไฟล์ข้อความโดยใช้ java.io.FileReader แล้วแสดงอักขระเหล่านั้นบนหน้าจอโดยใช้ System.out.println () หากไฟล์เขียนด้วยการเข้ารหัส Cp866 เอาต์พุตจะทำงานอย่างถูกต้อง ยกเว้นตัวอักษร Ш อีกครั้ง

    การแปลงไบต์โดยตรง<->ถ่าน

    ข้อผิดพลาดนี้เป็นที่ชื่นชอบในหมู่โปรแกรมเมอร์ Java ต่างประเทศ มีการกล่าวถึงในรายละเอียดบางส่วนในตอนต้นของคำอธิบาย หากคุณเคยดูแหล่งที่มาของคนอื่น ให้ใส่ใจกับการแปลงประเภทที่ชัดเจนเสมอ - (ไบต์) หรือ (ถ่าน) คราดมักถูกฝังอยู่ในสถานที่ดังกล่าว

    อัลกอริทึมในการค้นหาปัญหาเกี่ยวกับตัวอักษรรัสเซีย

    หากคุณไม่รู้ว่าตัวอักษรรัสเซียหายไปที่ใดในโปรแกรมของคุณ คุณสามารถลองทดสอบครั้งต่อไปได้ โปรแกรมใด ๆ สามารถถือเป็นตัวประมวลผลข้อมูลอินพุตได้ ตัวอักษรรัสเซียเป็นข้อมูลเดียวกัน โดยทั่วไปแล้วจะผ่านการประมวลผลสามขั้นตอน: อ่านจากที่ใดที่หนึ่งไปยังหน่วยความจำของโปรแกรม (อินพุต) ประมวลผลภายในโปรแกรม และแสดงต่อผู้ใช้ (เอาต์พุต) เพื่อระบุตำแหน่งของปัญหา แทนที่จะใช้ข้อมูลเพื่อเย็บบรรทัดทดสอบต่อไปนี้ลงในซอร์สโค้ด: "ABC \ u0410 \ u0411 \ u0412" แล้วลองส่งออก หลังจากนั้นดูสิ่งที่คุณได้รับ:

    • หากคุณเห็น "ABVABV" แสดงว่าการรวบรวมแหล่งที่มาและผลลัพธ์ทำงานอย่างถูกต้องสำหรับคุณ
    • หากคุณเห็น "??? ABC" (หรืออักขระอื่นๆ ที่ไม่ใช่ "ABC" แทนตัวอักษรสามตัวแรก) แสดงว่าเอาต์พุตทำงานอย่างถูกต้อง แต่การรวบรวมแหล่งที่มานั้นผิดพลาด - เป็นไปได้มากว่าการเข้ารหัส ไม่ได้ระบุคีย์
    • ถ้าคุณเห็น "??????" (หรือสัญลักษณ์อื่นๆ ยกเว้น "ABC" แทนตัวอักษรสามตัวที่สอง) แสดงว่าเอาต์พุตทำงานไม่ถูกต้องสำหรับคุณ

    เมื่อกำหนดค่าเอาต์พุตและคอมไพล์แล้ว คุณก็สามารถหาอินพุตได้อย่างง่ายดายแล้ว หลังจากตั้งโซ่ทั้งชุดแล้ว ปัญหาต่างๆ ก็จะหมดไป

    เกี่ยวกับยูทิลิตี้ native2ascii

    ยูทิลิตีนี้เป็นส่วนหนึ่งของ Sun JDK และออกแบบมาเพื่อแปลงซอร์สโค้ดเป็นรูปแบบ ASCII มันอ่านไฟล์อินพุตโดยใช้การเข้ารหัสที่ระบุและเขียนอักขระในรูปแบบ "\ uXXXX" หากคุณระบุสวิตช์ -reverse จะทำการแปลงย้อนกลับ โปรแกรมนี้มีประโยชน์มากสำหรับการแปลงไฟล์ทรัพยากร (.properties) หรือสำหรับการประมวลผลแหล่งที่มา หากคุณสงสัยว่าสามารถคอมไพล์ไฟล์เหล่านี้บนคอมพิวเตอร์ที่มีการตั้งค่าภูมิภาคที่ไม่ใช่รัสเซียได้

    หากคุณรันโปรแกรมโดยไม่มีพารามิเตอร์ โปรแกรมจะทำงานกับอินพุตมาตรฐาน (stdin) และไม่แสดงคำใบ้คีย์เหมือนกับยูทิลิตี้อื่นๆ สิ่งนี้นำไปสู่ความจริงที่ว่าหลายคนไม่รู้ด้วยซ้ำว่าจำเป็นต้องระบุพารามิเตอร์ (ยกเว้นบางทีผู้ที่พบความแข็งแกร่งและความกล้าหาญในการดูเอกสาร :-) ในขณะเดียวกันยูทิลิตี้นี้สำหรับ งานที่ถูกต้องคุณต้องระบุการเข้ารหัสที่ใช้เป็นอย่างน้อย (ด้วยคีย์ -encoding) หากยังไม่เสร็จสิ้น ระบบจะใช้การเข้ารหัสเริ่มต้น (file.encoding) ซึ่งอาจแตกต่างไปจากที่คาดไว้เล็กน้อย เป็นผลให้เมื่อได้รับรหัสตัวอักษรที่ไม่ถูกต้อง (เนื่องจากการเข้ารหัสไม่ถูกต้อง) คุณสามารถใช้เวลามากในการค้นหาข้อผิดพลาดในรหัสที่ถูกต้องอย่างแน่นอน

    เกี่ยวกับวิธีการแปลงอักขระ

    หลายคนใช้วิธีนี้อย่างไม่ถูกต้อง อาจไม่เข้าใจถึงสาระสำคัญและข้อจำกัดของวิธีการทั้งหมด ได้รับการออกแบบมาเพื่อกู้คืนรหัสตัวอักษรที่ถูกต้องหากได้รับการตีความผิด สาระสำคัญของวิธีการนั้นง่าย: อาร์เรย์ไบต์ดั้งเดิมถูกกู้คืนจากอักขระที่ไม่ถูกต้องที่ได้รับโดยใช้หน้ารหัสที่เหมาะสม จากนั้น จากอาร์เรย์ของไบต์นี้ โดยใช้หน้าที่ถูกต้องแล้ว จะได้รหัสอักขระปกติ ตัวอย่าง:

    String res = สตริงใหม่ (src.getBytes ("ISO-8859-1"), "Cp1251");

    อาจมีปัญหาหลายประการในการใช้เทคนิคนี้ ตัวอย่างเช่น มีการใช้เพจที่ไม่ถูกต้องในการกู้คืน หรืออาจมีการเปลี่ยนแปลงในบางสถานการณ์ ปัญหาอีกประการหนึ่งอาจเป็นได้ว่าบางหน้ากำลังดำเนินการแปลงไบต์ที่คลุมเครือ<->ถ่าน ดูตัวอย่างเช่น คำอธิบายข้อผิดพลาดตามหมายเลข

    ดังนั้นคุณควรใช้วิธีนี้เฉพาะในกรณีที่รุนแรงที่สุดเมื่อไม่มีอะไรช่วยและคุณมีความคิดที่ชัดเจนว่าการแปลงอักขระไม่ถูกต้องเกิดขึ้นที่ใด

    อักษรรัสเซียและ MS JVM

    ไม่ชัดเจนด้วยเหตุผลอะไร แต่ไม่มีไฟล์ทั้งหมดสำหรับการเข้ารหัสตัวอักษรรัสเซีย acrome Cp1251 (พวกเขาอาจพยายามลดขนาดการแจกจ่ายด้วยวิธีนี้) หากคุณต้องการการเข้ารหัสอื่นๆ เช่น Cp866 คุณต้องเพิ่มคลาสที่เกี่ยวข้องลงใน CLASSPATH ยิ่งกว่านั้นคลาสจาก Sun JDK เวอร์ชันล่าสุดไม่พอดี - Sun ได้เปลี่ยนโครงสร้างมาเป็นเวลานาน ดังนั้นเวอร์ชันล่าสุดของคลาสกับ Microsoft จึงไม่พอดี (MS มีโครงสร้างจาก JDK 1.1.4) โดยหลักการแล้วบนเซิร์ฟเวอร์ Microsoft มีชุดการเข้ารหัสเพิ่มเติมครบชุด แต่มีไฟล์ขนาดประมาณ 3 เมตร และเซิร์ฟเวอร์ไม่รองรับการดาวน์โหลดต่อ :-) ฉันจัดการเพื่อดาวน์โหลดไฟล์นี้ ฉันจัดแพ็คเกจใหม่ด้วย jar คุณสามารถนำมาจากที่นี่

    หากคุณกำลังเขียนแอปเพล็ตที่ควรทำงานภายใต้ MS JVM และคุณจำเป็นต้องอ่านจากที่อื่น (เช่น จากไฟล์บนเซิร์ฟเวอร์) ไบต์ในการเข้ารหัสภาษารัสเซียที่ไม่ใช่ Cp1251 (เช่น ใน Cp866) คุณจะไม่ใช้อีกต่อไป สามารถใช้กลไกการเข้ารหัสมาตรฐานได้ - ห้ามไม่ให้แอปเพล็ตเพิ่มคลาสลงในแพ็คเกจระบบ ซึ่งในกรณีนี้คือแพ็คเกจ sun.io มีสองวิธีในการถอดรหัสไฟล์ใหม่บนเซิร์ฟเวอร์เป็น Cp1251 (หรือเป็น UTF-8) หรือก่อนที่จะแปลงจากไบต์เป็น Unicode ให้แปลงไบต์จากการเข้ารหัสที่ต้องการเป็น Cp1251

    Russification ของ Java สำหรับ Linux

    ฉันจะพูดทันที - ฉันไม่ได้ทำงานกับ Linux และข้อมูลที่ให้ไว้ที่นี่ได้รับจากผู้อ่านคำอธิบายนี้ หากคุณพบความไม่ถูกต้องหรือต้องการเพิ่ม - เขียนถึงฉัน

    มีปัญหาแบบขนานสองประการเมื่อ Cyrillizing JVM บน Linux:

    1. ปัญหาเอาต์พุตซิริลลิกในส่วนประกอบ GUI
    2. ปัญหาการป้อน Cyrillic จากแป้นพิมพ์ (ใน X11)

    ปัญหาการถอนเงินสามารถแก้ไขได้ด้วยวิธีนี้ (อัลกอริทึมนี้ส่งโดย Artemy E. Kapitula):

    1. ติดตั้งฟอนต์ Windows NT / 200 ttf ปกติใน X11 ฉันอยากจะแนะนำ Arial, Times New Roman, Courier New, Verdana และ Tahoma - และจะดีกว่าถ้าเชื่อมต่อไม่ผ่านเซิร์ฟเวอร์แบบอักษร แต่เป็นไดเร็กทอรีที่มีไฟล์
    2. เพิ่มไฟล์ font.properties.ru ต่อไปนี้ในไดเร็กทอรี $ JAVA_HOME / jre / lib

    ปัญหาอินพุตได้รับการแก้ไขโดยประมาณด้วยวิธีต่อไปนี้ (อัลกอริทึมนี้ส่งโดย Mikhail Ivanov):

    การตั้งค่าการป้อนตัวอักษรรัสเซียในการกำหนดค่าต่อไปนี้:

    • Mandrake Linux 7.1
    • XFree86 3.3.6
    • IBM Java 1.3.0 (เปิดตัว)

    ปัญหา:

    IBM Java 1.3 ไม่อนุญาตให้ป้อนตัวอักษรรัสเซีย (มองเห็นเป็นจระเข้) แม้ว่าจะมองเห็นได้บนฉลากและในเมนู

    ใช้ XIM (-> xkb) ใน AWT (สิ่งนี้ไม่ได้เลวร้ายในตัวเอง แค่ต้องจัดการอย่างระมัดระวังกับสิ่งต่าง ๆ + เครื่องมือ xkb บางตัวไม่ชอบมัน)

    กำหนดค่า xkb (และ locale (xkb โดยไม่มี locale ไม่ทำงาน))

    ขั้นตอน:

    1. สถานที่ถูกเปิดเผย (บางแห่งเช่น / etc / profile หรือ ~ / .bash_profile)
      ส่งออก LANG = ru_RU.KOI8-R ส่งออก LC_ALL = ru_RU.KOI8-R
    2. แก้ไข (หากยังไม่ได้ดำเนินการ) / etc / X11 / XF86Config. ส่วนแป้นพิมพ์ควรมีลักษณะดังนี้:
      XkbKeycodes "xfree86" XkbTypes "default" XkbCompat "default" XkbSymbols "ru" XkbGeometry "pc" XkbRules "xfree86" XkbModel "pc101" XkbLayout "ru" XkbOptions "grp: shift_toggle ciphers" "#ohm"
      หมายเหตุ: การตั้งค่า xkb นี้เข้ากันไม่ได้กับ xrus (และอื่น ๆ เช่น kikbd) ดังนั้นคุณจะต้องบอกลาพวกเขา
    3. X จะเริ่มต้นใหม่ คุณต้องตรวจสอบว่าทุกอย่างใช้งานได้ (เช่น ตัวอักษรรัสเซียในเทอร์มินัลและแอปพลิเคชัน)
    4. font.properties.ru -> $ JAVA_HOME / jre / lib
    5. fonts.dir -> $ JAVA_HOME / jre / lib / fonts
    6. cd $ JAVA_HOME / jre / lib / แบบอักษร; rm fonts.scale; ln -s fonts.dir fonts.scale

    ตอนนี้ควรป้อนตัวอักษรรัสเซียและแสดงเป็นวงสวิงโดยไม่มีปัญหา

หากคุณสังเกตเห็นความไม่ถูกต้องในคำอธิบายหรือต้องการเพิ่ม ให้เขียนถึงฉันเกี่ยวกับเรื่องนี้ แล้วชื่อของคุณจะปรากฏในรายการนี้ด้วย :-)

แนบการสนับสนุนอย่างเต็มที่สำหรับคำสั่ง .htaccess ...

การต่ออายุโดเมน 199-00 rub

การเข้ารหัสคือตารางอักขระ โดยที่ตัวอักษรแต่ละตัว (รวมถึงตัวเลขและอักขระพิเศษ) ถูกกำหนดหมายเลขเฉพาะ - รหัสอักขระ

มีเพียงครึ่งเดียวของตารางที่ได้มาตรฐานที่เรียกว่า รหัส ASCII - 128 อักขระแรกที่รวมตัวอักษรของอักษรละติน และไม่เคยมีปัญหากับพวกเขา ช่วงครึ่งหลังของตาราง (และมีทั้งหมด 256 อักขระ - ตามจำนวนสถานะที่หนึ่งไบต์สามารถรับได้) อยู่ภายใต้สัญลักษณ์ประจำชาติ และส่วนนี้จะแตกต่างกันไปในแต่ละประเทศ แต่เฉพาะในรัสเซียเท่านั้นที่สามารถเข้ารหัสได้มากถึง 5 แบบ คำว่า "แตกต่าง" หมายความว่าสัญลักษณ์เดียวกันสอดคล้องกับรหัสดิจิทัลที่แตกต่างกัน เหล่านั้น. หากเรากำหนดการเข้ารหัสข้อความไม่ถูกต้อง ความสนใจของเราจะถูกนำเสนอไปยังข้อความที่อ่านไม่ได้โดยสิ้นเชิง

การเข้ารหัสปรากฏขึ้นในอดีต การเข้ารหัสรัสเซียที่ใช้กันอย่างแพร่หลายครั้งแรกเรียกว่า KOI-8... มันถูกคิดค้นเมื่อระบบ UNIX ถูกปรับให้เข้ากับภาษารัสเซีย นี่เป็นย้อนกลับไปในทศวรรษที่เจ็ดสิบ - ก่อนการถือกำเนิดของคอมพิวเตอร์ส่วนบุคคล และจนถึงขณะนี้ใน UNIX นี่ถือเป็นการเข้ารหัสหลัก

จากนั้นคอมพิวเตอร์ส่วนบุคคลเครื่องแรกก็ปรากฏขึ้น และการเดินขบวนแห่งชัยชนะของ DOS ก็เริ่มขึ้น แทนที่จะใช้การเข้ารหัสที่คิดค้นขึ้นแล้ว Microsoft ตัดสินใจสร้างรหัสขึ้นมาเองซึ่งเข้ากันไม่ได้กับสิ่งใดๆ ปรากฏเป็นอย่างนี้ การเข้ารหัส DOS(หรือ 866 หน้ารหัส) อย่างไรก็ตาม มันแนะนำอักขระพิเศษสำหรับการวาดเฟรม ซึ่งใช้กันอย่างแพร่หลายในโปรแกรมที่เขียนภายใต้ DOS ตัวอย่างเช่นในนอร์ตันผู้บัญชาการคนเดียวกัน

คอมพิวเตอร์ Macintosh พัฒนาควบคู่ไปกับคอมพิวเตอร์ที่เข้ากันได้กับ IBM แม้จะมีความจริงที่ว่าส่วนแบ่งของพวกเขาในรัสเซียมีขนาดเล็กมาก แต่ถึงกระนั้นก็มีความจำเป็นสำหรับ Russification และแน่นอนว่ามีการคิดค้นการเข้ารหัสอื่น - MAC.

เวลาผ่านไป และในปี 1990 Microsoft ได้นำความสำเร็จครั้งแรกมาสู่ความสำเร็จ เวอร์ชั่น Windows 3.0-3.11. และควบคู่ไปกับการสนับสนุนภาษาประจำชาติ และอีกครั้ง มีการทำเคล็ดลับแบบเดียวกันกับ DOS ด้วยเหตุผลที่ไม่ทราบสาเหตุ พวกเขาไม่สนับสนุนสิ่งใด ๆ ที่มีอยู่ก่อนหน้านี้ (เช่นเดียวกับ OS / 2 ซึ่งใช้การเข้ารหัส DOS เป็นมาตรฐาน) แต่เสนอใหม่ ชนะการเข้ารหัส(หรือโค้ดเพจ 1251 ). โดยพฤตินัย มันได้กลายเป็นที่แพร่หลายมากที่สุดในรัสเซีย

และสุดท้าย ตัวเลือกการเข้ารหัสที่ห้าไม่ได้เชื่อมโยงกับบริษัทใดบริษัทหนึ่งอีกต่อไป แต่ด้วยความพยายามที่จะสร้างมาตรฐานการเข้ารหัสในระดับโลกทั้งใบ สิ่งนี้ทำโดย ISO ซึ่งเป็นองค์กรมาตรฐานสากล และเดาว่าพวกเขาทำอะไรกับภาษารัสเซีย? แทนที่จะเข้าใจผิดข้อใดข้อหนึ่งข้างต้นสำหรับ "รัสเซียมาตรฐาน" พวกเขากลับคิดอีกแบบหนึ่ง (!) และเรียกมันว่าชุดค่าผสมที่ย่อยไม่ได้เป็นเวลานาน ISO-8859-5... แน่นอนว่ามันกลับกลายเป็นว่าเข้ากันไม่ได้กับสิ่งใด และในขณะนี้การเข้ารหัสนี้แทบจะไม่ได้ใช้ที่ไหนเลย ดูเหมือนว่าจะใช้ในฐานข้อมูล Oracle เท่านั้น อย่างน้อยฉันไม่เคยเห็นข้อความในการเข้ารหัสนี้ อย่างไรก็ตาม รองรับในทุกเบราว์เซอร์

ตอนนี้เรากำลังดำเนินการสร้างการเข้ารหัสสากลใหม่ ( UNICODE) ซึ่งควรจะรวมภาษาทั้งหมดของโลกไว้ในตารางรหัสเดียว แล้วจะไม่มีปัญหาแน่นอน สำหรับสิ่งนี้ มีการจัดสรร 2 ไบต์สำหรับอักขระแต่ละตัว ดังนั้น จำนวนอักขระสูงสุดในตารางจึงขยายเป็น 65535 แต่ยังมีเวลาเหลืออีกมากก่อนที่ทุกคนจะเปลี่ยนไปใช้ UNICODE


ที่นี่เราพูดนอกเรื่องเล็กน้อยและพิจารณาเมตาแท็ก - Content-Type สำหรับการรับรู้แบบองค์รวม

เมตาแท็กใช้เพื่ออธิบายคุณสมบัติของเอกสาร HTML และต้องอยู่ภายในแท็ก HEAD เมตาแท็ก เช่น NAME มีข้อมูลที่เป็นข้อความเกี่ยวกับเอกสาร ผู้แต่ง และคำแนะนำบางประการสำหรับเครื่องมือค้นหา ตัวอย่างเช่น: หุ่นยนต์ คำอธิบาย คำสำคัญ ผู้แต่ง ลิขสิทธิ์

เมตาแท็กของประเภท HTTP-EQUIV ส่งผลต่อการสร้างส่วนหัวของเอกสารและกำหนดโหมดของการประมวลผล

Meta tag Content-Type - รับผิดชอบในการระบุประเภทเอกสารและการเข้ารหัสอักขระ

จำเป็นต้องใช้เมตาแท็กประเภทเนื้อหาโดยคำนึงถึงความแตกต่างบางประการเท่านั้น:

    ขั้นแรก การเข้ารหัสอักขระของข้อความต้องตรงกับการเข้ารหัสที่ระบุในแท็ก

    ประการที่สอง เซิร์ฟเวอร์ไม่ควรเปลี่ยนการเข้ารหัสข้อความเมื่อประมวลผลคำขอของเบราว์เซอร์

    ประการที่สาม หากเซิร์ฟเวอร์เปลี่ยนการเข้ารหัสข้อความ เซิร์ฟเวอร์จะต้องแก้ไขหรือลบเมตาแท็กประเภทเนื้อหา

การไม่ปฏิบัติตามข้อกำหนดเหล่านี้อาจนำไปสู่สิ่งต่อไปนี้: เว็บเซิร์ฟเวอร์จะตรวจหาการเข้ารหัสคำขอของลูกค้าโดยอัตโนมัติและมอบหน้าที่เข้ารหัสใหม่ให้กับเว็บเบราว์เซอร์ ในทางกลับกัน เบราว์เซอร์จะอ่านเอกสารตามเมตาแท็กประเภทเนื้อหา และหากการเข้ารหัสไม่ตรงกัน เอกสารจะสามารถอ่านได้หลังจากการจัดการที่ซับซ้อนหลายครั้งเท่านั้น โดยเฉพาะอย่างยิ่งสำหรับเบราว์เซอร์รุ่นเก่า

ความสนใจ! มีการแทรกแท็ก Meta Content-Type บ่อยมาก ตัวสร้าง HTMLรหัส.

ประเภทการเข้ารหัสที่พบบ่อยที่สุดคือ:

    Windows-1251 - ซิริลลิก (Windows)

    KOI8-r - ซิริลลิก (KOI8-R)

    cp866 - ซิริลลิก (DOS)

    Windows-1252 - ยุโรปตะวันตก (Windows)

    Windows-1250 - ยุโรปกลาง (Windows)

แน่นอนว่าทุกคนรู้จักเมตาแท็ก -

วี วัสดุนี้ใช้ข้อความที่ตัดตอนมาจากบทความจากเว็บไซต์ http://cherry-design.ru/

โดเมนที่เพิ่งเปิดตัวด้วย PR และ TIC:

บริการ http://reg.ru - ผู้ให้บริการโฮสต์และผู้รับจดทะเบียนโดเมนที่ใหญ่ที่สุด ให้คุณสมัครลงทะเบียนชื่อโดเมนซึ่งเพิ่งเปิดตัวโดยอดีตผู้ดูแลระบบ โดเมนที่เผยแพร่มักจะมีอัตรา TIC และ PR สูง และอาจน่าสนใจที่จะได้รับ

โดเมนที่เผยแพร่ .RU c TIC:
โดเมนพรีเมียมฟรี:

จำนวนข้อมูล: 7659 ไบต์

ในอดีต มีการจัดสรร 7 บิตเพื่อแสดงอักขระที่พิมพ์ (ข้อความเข้ารหัส) ในคอมพิวเตอร์เครื่องแรก 2 7 = 128. จำนวนนี้เพียงพอสำหรับการเข้ารหัสตัวพิมพ์เล็กทั้งหมดและ ตัวพิมพ์ใหญ่อักษรละติน ตัวเลขสิบ เครื่องหมายและวงเล็บต่างๆ ตรงนี้คือตาราง 7 บิตที่เป็น อักขระ ASCII(รหัสอเมริกันสแตนดาร์ดสำหรับการแลกเปลี่ยนข้อมูล) รายละเอียดข้อมูลซึ่งคุณจะได้รับด้วยคำสั่ง man ascii ระบบปฏิบัติการลินุกซ์.

เมื่อจำเป็นต้องเข้ารหัสตัวอักษรประจำชาติ 128 ตัวอักษรไม่เพียงพอ มีการตัดสินใจที่จะเปลี่ยนไปใช้การเข้ารหัสโดยใช้ 8 บิต (เช่น หนึ่งไบต์) เป็นผลให้จำนวนอักขระที่สามารถเข้ารหัสด้วยวิธีนี้จึงเท่ากับ 2 8 = 256 ในกรณีนี้ สัญลักษณ์ของตัวอักษรประจำชาติจะอยู่ที่ครึ่งหลังของตารางรหัส กล่าวคือ มีหน่วยอยู่ในบิตที่สำคัญที่สุดของไบต์ที่จัดสรรสำหรับการเข้ารหัสอักขระ นี่คือลักษณะที่ปรากฏของมาตรฐาน ISO 8859 ซึ่งมีการเข้ารหัสจำนวนมากสำหรับภาษาทั่วไปส่วนใหญ่

ในหมู่พวกเขาเป็นหนึ่งในตารางแรกสำหรับการเข้ารหัสตัวอักษรรัสเซีย - ISO 8859-5(ใช้คำสั่ง man iso_8859_1 เพื่อรับรหัสสำหรับตัวอักษรรัสเซียในตารางนี้)

โอนงาน ข้อมูลข้อความผ่านเครือข่ายพวกเขาถูกบังคับให้พัฒนาการเข้ารหัสอื่นสำหรับตัวอักษรรัสเซียที่เรียกว่า Koi8-R(รหัสแสดงข้อมูลเป็นแบบ 8 บิต เป็นสนิม) พิจารณาสถานการณ์เมื่อมีการส่งจดหมายที่มีข้อความภาษารัสเซียผ่าน อีเมล... มันเกิดขึ้นว่าในกระบวนการเดินทางผ่านเครือข่าย จดหมายถูกประมวลผลโดยโปรแกรมที่ทำงานกับการเข้ารหัส 7 บิต และศูนย์บิตที่แปด อันเป็นผลมาจากการเปลี่ยนแปลงนี้ รหัสอักขระลดลง 128 กลายเป็นรหัสอักขระของอักษรละติน จำเป็นต้องเพิ่มความเสถียรของข้อมูลข้อความที่ส่งเป็นศูนย์ 8 บิต

โชคดีที่ตัวอักษรซีริลลิกจำนวนมากมีการออกเสียงในอักษรละติน ตัวอย่างเช่น Ф และ F, P และ R มีตัวอักษรหลายตัวที่ตรงกันแม้ในโครงร่าง การจัดเรียงตัวอักษรรัสเซียใน ตารางรหัสในลักษณะที่รหัสของพวกเขาเกินรหัส ภาษาละตินที่คล้ายกันถึงจำนวน 128 พวกเขาประสบความสำเร็จที่การสูญเสียบิตที่ 8 ทำให้ข้อความเปลี่ยนไปแม้ว่าจะประกอบด้วยตัวอักษรละตินตัวเดียว แต่ก็ยังเข้าใจโดยผู้ใช้ที่พูดภาษารัสเซีย

เนื่องจากระบบปฏิบัติการทั้งหมดที่แพร่หลายในเวลานั้นวิธีที่สะดวกที่สุดในการทำงานกับเครือข่ายจึงถูกครอบงำโดยโคลนต่าง ๆ ของระบบปฏิบัติการ ระบบยูนิกซ์การเข้ารหัสนี้จึงกลายเป็นมาตรฐานโดยพฤตินัยในระบบเหล่านี้ ยังคงเป็นเช่นนี้ในลินุกซ์ และการเข้ารหัสนี้มักใช้ในการแลกเปลี่ยนจดหมายและข่าวสารบนอินเทอร์เน็ต

แล้วก็มาถึงยุค คอมพิวเตอร์ส่วนบุคคลและระบบปฏิบัติการ MS DOS เมื่อมันปรากฏออกมา การเข้ารหัส Koi8-R ไม่เหมาะสำหรับเธอ (เช่นเดียวกับ ISO 8859-5) ในตารางของเธอ ตัวอักษรรัสเซียบางตัวอยู่ในสถานที่เหล่านั้นซึ่งหลายโปรแกรมสันนิษฐานว่าเต็มไปด้วยภาพจำลอง (เส้นประแนวนอนและแนวตั้ง มุม ฯลฯ .) เป็นต้น) ดังนั้นจึงมีการคิดค้นการเข้ารหัสซีริลลิกอื่นในตารางที่ตัวอักษรรัสเซีย "ไหลไปรอบ ๆ " สัญลักษณ์กราฟิกจากทุกด้าน เรียกว่าการเข้ารหัสนี้ ทางเลือก(alt) เพราะเป็นทางเลือกแทนมาตรฐานอย่างเป็นทางการ การเข้ารหัส ISO-8859-5 ข้อได้เปรียบที่เถียงไม่ได้ของการเข้ารหัสนี้คือตัวอักษรรัสเซียในนั้นถูกจัดเรียงตามลำดับตัวอักษร

หลังจากการปรากฏตัวของ Windows จาก Microsoft ปรากฎว่าการเข้ารหัสทางเลือกด้วยเหตุผลบางอย่างไม่เหมาะกับมัน การย้ายตัวอักษรรัสเซียในตารางอีกครั้ง (มีโอกาส - ไม่จำเป็นต้องมีกราฟิกหลอกใน Windows) เราได้รับการเข้ารหัส Windows 1251(วิน-1251)

แต่เทคโนโลยีคอมพิวเตอร์มีการปรับปรุงอย่างต่อเนื่องและในปัจจุบันมีโปรแกรมจำนวนมากขึ้นเริ่มสนับสนุนมาตรฐาน Unicode ซึ่งช่วยให้คุณเข้ารหัสเกือบทุกภาษาและภาษาถิ่นของชาวโลก

ดังนั้นในระบบปฏิบัติการที่ต่างกัน การตั้งค่าจะถูกกำหนดให้กับการเข้ารหัสที่แตกต่างกัน เพื่อที่จะให้สามารถอ่านและแก้ไขข้อความที่พิมพ์ด้วยการเข้ารหัสแบบอื่นได้ จึงมีการใช้โปรแกรมแปลงข้อความภาษารัสเซีย บาง โปรแกรมแก้ไขข้อความมีตัวแปลงสัญญาณในตัวที่ให้คุณอ่านข้อความในการเข้ารหัสต่างๆ (Word ฯลฯ) ในการแปลงไฟล์ เราจะใช้ยูทิลิตี้จำนวนหนึ่งใน Linux ซึ่งมีจุดประสงค์ที่ชัดเจนจากชื่อ: alt2koi, win2koi, koi2win, alt2win, win2alt, koi2alt (จากที่ไหนที่หมายเลข 2 (สอง) มีความคล้ายคลึงกันใน เสียงคำบุพบท to ระบุทิศทาง) คำสั่งเหล่านี้มีรูปแบบเดียวกัน: command<входной_файл >เอาท์พุต_ไฟล์.

ตัวอย่าง

มาเข้ารหัสข้อความที่พิมพ์ในโปรแกรมแก้ไขแก้ไขในสภาพแวดล้อม MS DOS ใหม่ในการเข้ารหัส Koi8-R เมื่อต้องการทำสิ่งนี้ ให้รันคำสั่ง

alt2koi file1.txt> filenew

เนื่องจากบรรทัดฟีดถูกเข้ารหัสต่างกันใน MS DOS และ Linux ขอแนะนำให้รันคำสั่ง "fromdos":

fromdos filenew> file2.txt

คำสั่งย้อนกลับเรียกว่า "todos" และมีรูปแบบเดียวกัน

ตัวอย่าง

มาจัดเรียงไฟล์ List.txt ที่มีรายชื่อนามสกุลและเตรียมการเข้ารหัส Koi8-R ตามลำดับตัวอักษร ลองใช้คำสั่ง sort ซึ่งเรียงลำดับไฟล์ข้อความจากน้อยไปหามากหรือจากมากไปหาน้อยของรหัสอักขระ หากคุณสมัครทันที ตัวอย่างเช่น จดหมาย วีจะอยู่ท้ายรายการ คล้ายกับอักษรละติน วี... จำไว้ว่าในการเข้ารหัสทางเลือกอื่น ตัวอักษรรัสเซียถูกจัดเรียงตามตัวอักษรอย่างเคร่งครัด เราจะดำเนินการหลายอย่าง: เข้ารหัสข้อความเป็นการเข้ารหัสทางเลือก จัดเรียง และส่งคืนการเข้ารหัส Koi8-R โดยใช้ไพพ์ไลน์คำสั่ง เราจะได้

koi2alt List.txt | เรียงลำดับ | alt2koi> List_Sort.txt

ในลีนุกซ์รุ่นปัจจุบัน ปัญหามากมายที่เกี่ยวข้องกับ การแปลเป็นภาษาท้องถิ่น ซอฟต์แวร์... โดยเฉพาะอย่างยิ่ง ยูทิลิตี้ sort ตอนนี้คำนึงถึงลักษณะเฉพาะของการเข้ารหัส Koi8-R และเพื่อจัดเรียงไฟล์ตามลำดับตัวอักษร เพียงแค่รันคำสั่ง

การเข้ารหัส

เมื่อฉันเริ่มเขียนโปรแกรมในภาษา C โปรแกรมแรกของฉัน (นอกเหนือจาก HelloWorld) เป็นโปรแกรมสำหรับแปลงไฟล์ข้อความจากการเข้ารหัส GOST หลัก (จำสิ่งนี้ได้ไหม :-) เป็นโปรแกรมอื่น ย้อนกลับไปในปี 1991 มีการเปลี่ยนแปลงมากมายตั้งแต่นั้นมา แต่น่าเสียดายที่โปรแกรมดังกล่าวไม่ได้สูญเสียความเกี่ยวข้องตลอด 10 ปีที่ผ่านมา มีการสะสมข้อมูลมากเกินไปในการเข้ารหัสต่างๆ และใช้โปรแกรมมากเกินไปที่สามารถทำงานได้เพียงโปรแกรมเดียว สำหรับภาษารัสเซียนั้น มีการเข้ารหัสที่แตกต่างกันอย่างน้อยสิบแบบ ซึ่งทำให้ปัญหาสับสนมากยิ่งขึ้น

การเข้ารหัสเหล่านี้มาจากไหนและมีไว้เพื่ออะไร โดยธรรมชาติแล้ว คอมพิวเตอร์สามารถทำงานได้กับตัวเลขเท่านั้น เพื่อเก็บตัวอักษรไว้ในหน่วยความจำของคอมพิวเตอร์ จำเป็นต้องกำหนดตัวเลขให้กับตัวอักษรแต่ละตัว ยิ่งไปกว่านั้น จำนวนที่น้อยกว่าที่ควรจะเป็น - ยิ่งมีเลขฐานสองน้อยลงเท่าใดก็ยิ่งสามารถใช้หน่วยความจำได้อย่างมีประสิทธิภาพมากขึ้นเท่านั้น ความสอดคล้องระหว่างชุดของอักขระและตัวเลขนี้เป็นการเข้ารหัสจริงๆ ความปรารถนาที่จะบันทึกหน่วยความจำไม่ว่าจะเสียค่าใช้จ่ายใด ๆ เช่นเดียวกับการแตกแยกของนักวิทยาศาสตร์คอมพิวเตอร์กลุ่มต่าง ๆ นำไปสู่สถานะปัจจุบัน วิธีการเข้ารหัสที่พบบ่อยที่สุดในขณะนี้คือการใช้หนึ่งไบต์ (8 บิต) ต่ออักขระหนึ่งตัว ซึ่งกำหนดจำนวนอักขระทั้งหมดเป็น 256 ตัว ชุดของอักขระ 128 ตัวแรกเป็นมาตรฐาน (ชุด ASCII) และเหมือนกันในการเข้ารหัสทั่วไปทั้งหมด (การเข้ารหัสเหล่านั้นที่ไม่ได้ใช้งานจริงอยู่แล้ว) ตัวอักษรแองกลิกันและสัญลักษณ์เครื่องหมายวรรคตอนอยู่ในช่วงนี้ ซึ่งกำหนดความมีชีวิตชีวาอันน่าทึ่งในระบบคอมพิวเตอร์ :-) ภาษาอื่นไม่ค่อยดีนัก - พวกเขาทั้งหมดต้องรวมกลุ่มกันใน 128 ตัวเลขที่เหลือ

Unicode

ในช่วงปลายทศวรรษ 1980 หลายคนตระหนักถึงความจำเป็นในการสร้างมาตรฐานเดียวสำหรับการเข้ารหัสอักขระ ซึ่งนำไปสู่การเกิดขึ้นของ Unicode Unicode คือความพยายามที่จะแก้ไขตัวเลขเฉพาะสำหรับอักขระตัวใดตัวหนึ่งทันทีและสำหรับทั้งหมด เป็นที่ชัดเจนว่า 256 ตัวอักษรจะไม่พอดีกับความต้องการทั้งหมดที่นี่ เป็นเวลานานดูเหมือนว่า 2 ไบต์ (65536 อักขระ) น่าจะเพียงพอ แต่ไม่ใช่ - เวอร์ชันล่าสุดของมาตรฐาน Unicode (3.1) ได้กำหนดอักขระแล้ว 94,140 ตัว สำหรับจำนวนอักขระดังกล่าว คุณอาจต้องใช้ 4 ไบต์อยู่แล้ว (4294967296 อักขระ) อาจจะเพียงพอในขณะที่ ... :-)

ชุดอักขระ Unicode ประกอบด้วยตัวอักษรทุกประเภทที่มีเครื่องหมายขีดกลางและปาเพนดิลกิ กรีก คณิตศาสตร์ อักษรอียิปต์โบราณ สัญลักษณ์กราฟิกหลอก ฯลฯ เป็นต้น รวมถึงอักขระซีริลลิกที่เราชื่นชอบ (ช่วงของค่าคือ 0x0400-0x04ff) . ดังนั้นจึงไม่มีการเลือกปฏิบัติในด้านนี้

หากคุณสนใจรหัสอักขระเฉพาะ จะสะดวกที่จะใช้โปรแกรม "ผังอักขระ" จาก WinNT เพื่อดู ตัวอย่างเช่น นี่คือช่วง Cyrillic:

หากคุณมีระบบปฏิบัติการอื่นหรือสนใจในการตีความอย่างเป็นทางการ สามารถดูแผนภูมิแบบเต็มได้ที่เว็บไซต์ทางการของ Unicode (http://www.unicode.org/charts/web.html)

ประเภทอักขระและไบต์

Java มีประเภทข้อมูลถ่านแยกต่างหาก 2 ไบต์สำหรับอักขระ สิ่งนี้มักจะสร้างความสับสนในใจของผู้เริ่มต้น (โดยเฉพาะอย่างยิ่งหากพวกเขาได้ตั้งโปรแกรมในภาษาอื่นเช่น C / C ++ ก่อนหน้านี้) เนื่องจากภาษาอื่นๆ ส่วนใหญ่ใช้ประเภทข้อมูล 1 ไบต์ในการประมวลผลอักขระ ตัวอย่างเช่น ใน C / C ++ ถ่านส่วนใหญ่จะใช้สำหรับการจัดการอักขระและการจัดการไบต์ - ไม่มีการแยก Java มีประเภทของตัวเองสำหรับไบต์ - ประเภทไบต์ ดังนั้น ถ่านแบบ C จึงสอดคล้องกับไบต์ของ Java และถ่าน Java จากโลก C นั้นใกล้เคียงกับประเภท wchar_t มากที่สุด จำเป็นต้องแยกแนวคิดของอักขระและไบต์ออกอย่างชัดเจน ไม่เช่นนั้นจะรับประกันความเข้าใจผิดและปัญหา

Java ใช้มาตรฐาน Unicode สำหรับการเข้ารหัสอักขระมาเกือบตั้งแต่เริ่มก่อตั้ง ฟังก์ชันไลบรารี Java คาดว่าจะเห็นอักขระ Unicode ในตัวแปรถ่าน โดยหลักการแล้ว คุณสามารถใส่อะไรก็ได้ - ตัวเลขคือตัวเลข โปรเซสเซอร์จะทนทานทุกอย่าง แต่สำหรับการประมวลผลใดๆ ฟังก์ชันไลบรารีจะทำหน้าที่ตามสมมติฐานว่าได้รับการเข้ารหัส Unicode ดังนั้นคุณจึงสามารถสรุปได้อย่างปลอดภัยว่าการเข้ารหัสอักขระนั้นได้รับการแก้ไขแล้ว แต่นี่อยู่ใน JVM เมื่อข้อมูลถูกอ่านจากภายนอกหรือส่งผ่านภายนอก จะสามารถแสดงได้เพียงประเภทเดียวเท่านั้น - ประเภทไบต์ ประเภทอื่นๆ ทั้งหมดสร้างขึ้นจากไบต์ ขึ้นอยู่กับรูปแบบข้อมูลที่ใช้ นี่คือจุดเริ่มต้นของการเข้ารหัส - ใน Java เป็นเพียงรูปแบบข้อมูลสำหรับการถ่ายโอนอักขระซึ่งใช้เพื่อสร้างข้อมูลประเภทถ่าน สำหรับแต่ละโค้ดเพจ ไลบรารีมีคลาสการแปลง 2 คลาส (ByteToChar และ CharToByte) คลาสเหล่านี้อยู่ในแพ็คเกจ sun.io หากไม่พบอักขระที่สอดคล้องกันเมื่อแปลงจากถ่านเป็นไบต์จะถูกแทนที่ด้วยอักขระ ?

อย่างไรก็ตาม ไฟล์โค้ดเพจเหล่านี้ใน JDK 1.1 เวอร์ชันแรกๆ บางเวอร์ชันมีข้อบกพร่องที่ทำให้เกิดข้อผิดพลาดในการแปลงหรือแม้แต่ข้อยกเว้นรันไทม์ ตัวอย่างเช่น สิ่งนี้เกี่ยวข้องกับการเข้ารหัส KOI8_R สิ่งที่ดีที่สุดที่ควรทำขณะทำเช่นนี้คือการอัปเกรดเป็นเวอร์ชันที่ใหม่กว่า เมื่อพิจารณาจากคำอธิบายของ Sun ปัญหาเหล่านี้ส่วนใหญ่ได้รับการแก้ไขแล้วใน JDK 1.1.6

ก่อน JDK 1.4 ชุดของการเข้ารหัสที่ใช้ได้ถูกกำหนดโดยผู้จำหน่าย JDK เท่านั้น เริ่มต้นด้วย 1.4 API ใหม่ได้ปรากฏขึ้นแล้ว (แพ็คเกจ java.nio.charset) ซึ่งคุณสามารถสร้างการเข้ารหัสของคุณเองได้ (เช่น รองรับโปรแกรมที่ไม่ค่อยได้ใช้ แต่จำเป็นอย่างยิ่งสำหรับคุณ)

คลาสสตริง

ในกรณีส่วนใหญ่ Java จะใช้อ็อบเจ็กต์ประเภท java.lang.String เพื่อแสดงสตริง นี่คือคลาสปกติที่เก็บอาร์เรย์ของอักขระ (char) ไว้ภายในและมีวิธีการที่มีประโยชน์มากมายสำหรับการจัดการอักขระ สิ่งที่น่าสนใจที่สุดคือตัวสร้างที่มีอาร์เรย์ไบต์เป็นพารามิเตอร์แรกและเมธอด getBytes () ด้วยวิธีการเหล่านี้ คุณสามารถทำการแปลงจากไบต์อาร์เรย์เป็นสตริงได้ และในทางกลับกัน เพื่อระบุการเข้ารหัสที่จะใช้พร้อมกัน เมธอดเหล่านี้มีพารามิเตอร์สตริงที่ตั้งชื่อ ตัวอย่างเช่น วิธีแปลงไบต์จาก KOI-8 เป็น Windows-1251 มีดังนี้

// ข้อมูลที่เข้ารหัส KOI-8ไบต์ koi8Data = ...; // แปลงจาก KOI-8 เป็น Unicodeสตริงสตริง = สตริงใหม่ (koi8Data, "KOI8_R"); // แปลงจาก Unicode เป็น Windows-1251ไบต์ winData = string.getBytes ("Cp1251");

รายการการเข้ารหัส 8 บิตที่มีอยู่ใน JDK สมัยใหม่และตัวอักษรรัสเซียที่รองรับอยู่ด้านล่างในส่วน

เนื่องจากการเข้ารหัสเป็นรูปแบบข้อมูลสำหรับอักขระ นอกเหนือจากการเข้ารหัส 8 บิตที่คุ้นเคยใน Java แล้ว ยังมีการเข้ารหัสแบบหลายไบต์ในระดับที่เท่ากัน ซึ่งรวมถึง UTF-8, UTF-16, Unicode เป็นต้น ตัวอย่างเช่น วิธีรับไบต์ในรูปแบบ UnicodeLittleUnmarked (การเข้ารหัส Unicode 16 บิต ไบต์ต่ำก่อน ไม่มีเครื่องหมายลำดับไบต์):

// แปลงจาก Unicode เป็น Unicodeข้อมูลไบต์ = string.getBytes ("UnicodeLittleUnmarked");

มันง่ายที่จะทำผิดพลาดกับการแปลงดังกล่าว - หากการเข้ารหัสข้อมูลไบต์ไม่ตรงกับพารามิเตอร์ที่ระบุเมื่อแปลงจากไบต์เป็นถ่าน การบันทึกจะไม่ถูกดำเนินการอย่างถูกต้อง บางครั้งหลังจากนั้น คุณสามารถดึงอักขระที่ถูกต้องออกมาได้ แต่บ่อยครั้งกว่านั้น ข้อมูลบางส่วนจะสูญหายไปอย่างแก้ไขไม่ได้

ในโปรแกรมจริง ไม่สะดวกที่จะระบุโค้ดเพจให้ชัดเจนเสมอไป (แม้ว่าจะเชื่อถือได้มากกว่าก็ตาม) ด้วยเหตุนี้จึงมีการแนะนำการเข้ารหัสเริ่มต้น โดยค่าเริ่มต้น ขึ้นอยู่กับระบบและการตั้งค่าของระบบ (สำหรับ Windows รัสเซีย จะใช้การเข้ารหัส Cp1251) และใน JDK รุ่นเก่า สามารถเปลี่ยนได้โดยการตั้งค่าคุณสมบัติของระบบ file.encoding ใน JDK 1.3 การเปลี่ยนการตั้งค่านี้บางครั้งใช้ได้ แต่บางครั้งก็ใช้ไม่ได้ มีสาเหตุดังต่อไปนี้: ในตอนแรก file.encoding ถูกตั้งค่าตามการตั้งค่าภูมิภาคของคอมพิวเตอร์ การอ้างอิงการเข้ารหัสเริ่มต้นจะจดจำไว้ภายในระหว่างการแปลงครั้งแรก ในกรณีนี้ จะใช้ file.encoding แต่การแปลงนี้เกิดขึ้นก่อนการใช้อาร์กิวเมนต์การเริ่มต้น JVM (อันที่จริงแล้ว เมื่อแยกวิเคราะห์) อันที่จริง Sun กล่าวว่าคุณสมบัตินี้สะท้อนถึงการเข้ารหัสของระบบและไม่ควรเปลี่ยนแปลงในบรรทัดคำสั่ง (ดูตัวอย่าง ความคิดเห็นเกี่ยวกับ BugID) อย่างไรก็ตาม ใน JDK 1.4 Beta 2 การเปลี่ยนแปลงการตั้งค่านี้อีกครั้งเริ่มมีผล นี่คือการเปลี่ยนแปลงอย่างมีสติหรือผลข้างเคียงที่สามารถหายไปได้อีกครั้ง - แกะซันยังไม่ได้ให้คำตอบที่ชัดเจน

การเข้ารหัสนี้ใช้เมื่อไม่ได้ระบุชื่อเพจไว้อย่างชัดเจน สิ่งนี้ควรจำไว้เสมอ - Java จะไม่พยายามคาดเดาการเข้ารหัสของไบต์ที่คุณส่งผ่านเพื่อสร้างสตริง (มันจะไม่สามารถอ่านความคิดของคุณเกี่ยวกับ :-) เพียงแค่ใช้การเข้ารหัสเริ่มต้นปัจจุบัน เพราะ การตั้งค่านี้จะเหมือนกันสำหรับการแปลงทั้งหมด บางครั้งคุณอาจประสบปัญหา

ในการแปลงจากไบต์เป็นอักขระและในทางกลับกัน ให้ใช้ เท่านั้นโดยวิธีการเหล่านี้ ในกรณีส่วนใหญ่ การแปลงประเภทอย่างง่ายจะไม่สามารถใช้ได้ - การเข้ารหัสอักขระจะไม่ถูกนำมาพิจารณา ตัวอย่างเช่น หนึ่งในข้อผิดพลาดที่พบบ่อยที่สุดคือการอ่านข้อมูลแบบไบต์โดยใช้เมธอด read () จาก InputStream จากนั้นจึงส่งค่าผลลัพธ์เป็นประเภทถ่าน:

InputStream คือ = ..; int ข; StringBuffer sb = ใหม่ StringBuffer (); ในขณะที่ ((b = is.read ())! = - 1) (sb.append ((char) b); // <- так делать нельзя ) สตริง s = sb.toString ();

ให้ความสนใจกับการพิมพ์ดีด - "(อักขระ) ข" ค่าไบต์จะถูกคัดลอกไปยังถ่านแทนการเข้ารหัสซ้ำ (ช่วงของค่าคือ 0-0xFF ไม่ใช่ช่วงที่มีอักษรซีริลลิก) การคัดลอกนี้สอดคล้องกับการเข้ารหัส ISO-8859-1 (ซึ่งหนึ่งต่อหนึ่งสอดคล้องกับค่า Unicode 256 ค่าแรก) ซึ่งหมายความว่าเราสามารถสันนิษฐานได้ว่ารหัสนี้ใช้งานได้ง่าย (แทนที่จะเป็นรหัสที่อักขระใน ข้อมูลดั้งเดิมจะถูกเข้ารหัสจริง) หากคุณพยายามแสดงค่าที่ได้รับจะมีคำถามหรือ krakozyably บนหน้าจอ ตัวอย่างเช่น เมื่ออ่านสตริง "ABC" ในการเข้ารหัส Windows ข้อมูลเช่นนี้สามารถแสดงได้อย่างง่ายดาย: "АÁВ" โค้ดประเภทนี้มักเขียนโดยโปรแกรมเมอร์ในฝั่งตะวันตก ซึ่งใช้ได้กับตัวอักษรภาษาอังกฤษ ไม่เป็นไร การแก้ไขรหัสนี้เป็นเรื่องง่าย - คุณเพียงแค่ต้องแทนที่ StringBuffer ด้วย ByteArrayOutputStream:

InputStream คือ = ..; int ข; ByteArrayOutputStream baos = ใหม่ ByteArrayOutputStream (); ในขณะที่ ((b = is.read ())! = - 1) (baos.write (b);) // แปลงไบต์เป็นสตริงโดยใช้การเข้ารหัสเริ่มต้นสตริง s = baos.toString (); // หากคุณต้องการการเข้ารหัสเฉพาะ ให้ระบุเมื่อเรียกใช้ toString (): // // s = baos.toString ("Cp1251");
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับข้อผิดพลาดทั่วไป โปรดดูส่วน

การเข้ารหัสตัวอักษรรัสเซีย 8 บิต

นี่คือการเข้ารหัส 8 บิตหลักของตัวอักษรรัสเซียที่แพร่หลาย:

นอกจากชื่อหลักแล้ว คุณสามารถใช้คำพ้องความหมายได้ ชุดของพวกเขาอาจแตกต่างกันใน JDK เวอร์ชันต่างๆ นี่คือรายการจาก JDK 1.3.1:

  • CP1251:
    • Windows-1251
  • CP866:
    • IBM866
    • IBM-866
    • CP866
    • CSIBM866
  • KOI8_R:
    • KOI8-R
    • CSKOI8R
  • ISO8859_5:
    • ISO8859-5
    • ISO-8859-5
    • ISO_8859-5
    • ISO_8859-5: 1988
    • ISO-IR-144
    • 8859_5
    • ซิริลลิก
    • CSISOละตินCyrillic
    • IBM915
    • IBM-915
    • Cp915

นอกจากนี้ คำพ้องความหมาย ซึ่งแตกต่างจากชื่อหลัก ไม่คำนึงถึงตัวพิมพ์เล็ก-ใหญ่ ซึ่งเป็นคุณลักษณะของการนำไปใช้งาน

เป็นที่น่าสังเกตว่าการเข้ารหัสเหล่านี้อาจไม่พร้อมใช้งานใน JVM บางตัว ตัวอย่างเช่น คุณสามารถดาวน์โหลด JRE สองเวอร์ชันที่แตกต่างกันจากเว็บไซต์ Sun - US และ International ในเวอร์ชันสหรัฐอเมริกา มีเพียง ISO-8859-1, ASCII, Cp1252, UTF8, UTF16 และ Unicode แบบไบต์คู่หลายรูปแบบ อย่างอื่นมีเฉพาะในเวอร์ชันสากลเท่านั้น บางครั้งด้วยเหตุนี้ คุณจึงสามารถใช้คราดด้วยการเปิดตัวโปรแกรม แม้ว่าจะไม่ต้องการตัวอักษรรัสเซียก็ตาม ข้อผิดพลาดทั่วไปที่เกิดขึ้นขณะทำสิ่งนี้:

เกิดข้อผิดพลาดระหว่างการเริ่มต้น VM java / lang / ClassNotFoundException: sun / io / ByteToCharCp1251

มันเกิดขึ้นเนื่องจากเดาได้ไม่ยากเนื่องจาก JVM ตามการตั้งค่าภูมิภาคของรัสเซียพยายามตั้งค่าการเข้ารหัสเริ่มต้นใน Cp1251 แต่ตั้งแต่ คลาสของการสนับสนุนดังกล่าวไม่มีในเวอร์ชันสหรัฐอเมริกา

ไฟล์และสตรีมข้อมูล

เช่นเดียวกับไบต์ที่แยกตามแนวคิดจากอักขระ Java จะแยกความแตกต่างระหว่างสตรีมไบต์และสตรีมอักขระ การทำงานกับไบต์แสดงโดยคลาสที่สืบทอดคลาส InputStream หรือ OutputStream โดยตรงหรือโดยอ้อม (รวมถึงคลาส RandomAccessFile ที่ไม่ซ้ำกัน) การทำงานกับสัญลักษณ์นั้นแสดงโดยคลาส Reader / Writer อันแสนหวาน (และลูกหลานของพวกเขาแน่นอน)

สตรีมของไบต์ใช้เพื่ออ่าน / เขียนไบต์ที่ไม่ได้แปลง ถ้าคุณรู้ว่าไบต์แสดงเฉพาะอักขระในการเข้ารหัสบางอย่าง คุณสามารถใช้คลาสตัวแปลงพิเศษ InputStreamReader และ OutputStreamWriter เพื่อรับกระแสของอักขระและทำงานกับมันโดยตรง ซึ่งมักจะมีประโยชน์สำหรับไฟล์ข้อความธรรมดาหรือเมื่อทำงานกับโปรโตคอลเครือข่ายของอินเทอร์เน็ตจำนวนมาก ในกรณีนี้ การเข้ารหัสอักขระถูกระบุในตัวสร้างของคลาสตัวแปลง ตัวอย่าง:

// สตริง Unicode สตริงสตริง = "..."; // เขียนสตริงลงในไฟล์ข้อความในการเข้ารหัส Cp866 PrintWriter pw = PrintWriter ใหม่ // คลาสพร้อมเมธอดสำหรับเขียนสตริง(ใหม่ OutputStreamWriter // คลาสตัวแปลง(FileOutputStream ใหม่ ("file.txt"), "Cp866"); pw.println (สตริง); // เขียนบรรทัดไปที่ไฟล์ pw.close ();

หากสตรีมอาจมีข้อมูลในการเข้ารหัสที่แตกต่างกัน หรืออักขระผสมกับข้อมูลไบนารีอื่น ๆ จะเป็นการดีกว่าที่จะอ่านและเขียนไบต์อาร์เรย์ (ไบต์) และใช้วิธีการที่กล่าวถึงแล้วของคลาส String สำหรับการแปลง ตัวอย่าง:

// สตริง Unicode สตริงสตริง = "..."; // เขียนสตริงลงในไฟล์ข้อความด้วยการเข้ารหัสสองแบบ (Cp866 และ Cp1251)ระบบปฏิบัติการ OutputStream = FileOutputStream ใหม่ ("file.txt"); // class สำหรับเขียนไบต์ลง file // เขียนสตริงในการเข้ารหัส Cp866 os.write (string.getBytes ("Cp866")); // เขียนสตริงในการเข้ารหัส Cp1251 os.write (string.getBytes ("Cp1251")); os.close ();

คอนโซลใน Java มักจะแสดงโดยสตรีม แต่น่าเสียดายที่ไม่ใช่อักขระ แต่เป็นไบต์ ความจริงก็คือกระแสอักขระปรากฏใน JDK 1.1 เท่านั้น (พร้อมกับกลไกการเข้ารหัสทั้งหมด) และการเข้าถึงคอนโซล I / O ได้รับการออกแบบใน JDK 1.0 ซึ่งนำไปสู่การปรากฏตัวของประหลาดในรูปแบบของคลาส PrintStream คลาสนี้ใช้ในตัวแปร System.out และ System.err ซึ่งให้การเข้าถึงเอาต์พุตไปยังคอนโซล ตามบัญชีทั้งหมด นี่เป็นสตรีมของไบต์ แต่มีวิธีการมากมายในการเขียนสตริง เมื่อคุณเขียนสตริงลงไป มันจะแปลงเป็นไบต์โดยใช้การเข้ารหัสเริ่มต้น ซึ่งมักจะไม่ยอมรับในกรณีของ Windows - การเข้ารหัสเริ่มต้นจะเป็น Cp1251 (Ansi) และสำหรับหน้าต่างคอนโซล คุณมักจะต้องใช้ Cp866 ( OEM). ข้อผิดพลาดนี้ได้รับการบันทึกในปีที่ 97 () แต่ดูเหมือนว่า Sun-sheep จะไม่รีบแก้ไข เนื่องจากไม่มีวิธีการตั้งค่าการเข้ารหัสใน PrintStream เพื่อแก้ปัญหานี้ คุณสามารถแทนที่คลาสมาตรฐานด้วยคลาสของคุณเองโดยใช้วิธี System.setOut () และ System.setErr () ตัวอย่างเช่น นี่เป็นการเริ่มต้นตามปกติในโปรแกรมของฉัน:

... public static void main (สตริง args) ( // ตั้งค่าเอาต์พุตของข้อความคอนโซลในการเข้ารหัสที่ต้องการลอง (สตริง consoleEnc = System.getProperty ("console.encoding", "Cp866"); System.setOut (CodepagePrintStream ใหม่ (System.out, consoleEnc)); System.setErr (CodepagePrintStream ใหม่ (System.err, consoleEnc)); ) จับ (UnsupportedEncodingException e) (System.out.println ("ไม่สามารถตั้งค่าหน้ารหัสคอนโซล:" + e);) ...

คุณสามารถค้นหาแหล่งที่มาของคลาส CodepagePrintStream บนเว็บไซต์นี้: CodepagePrintStream.java

หากคุณกำลังสร้างรูปแบบข้อมูลด้วยตนเอง เราขอแนะนำให้คุณใช้การเข้ารหัสแบบหลายไบต์ตัวใดตัวหนึ่ง รูปแบบที่สะดวกที่สุดมักจะเป็น UTF8 - 128 ค่าแรก (ASCII) ในนั้นจะถูกเข้ารหัสในหนึ่งไบต์ซึ่งมักจะลดจำนวนข้อมูลทั้งหมดได้อย่างมาก (ไม่ใช่เพื่ออะไรที่การเข้ารหัสนี้เป็นพื้นฐานใน โลก XML) แต่ UTF8 มีข้อเสียอยู่อย่างหนึ่ง - จำนวนไบต์ที่ต้องการขึ้นอยู่กับรหัสอักขระ ในกรณีที่มีความสำคัญ คุณสามารถใช้รูปแบบ Unicode แบบสองไบต์ (UnicodeBig หรือ UnicodeLittle) ได้

ฐานข้อมูล

เพื่อที่จะอ่านอักขระจากฐานข้อมูลอย่างถูกต้อง มักจะเพียงพอที่จะบอกไดรเวอร์ JDBC ถึงการเข้ารหัสอักขระที่จำเป็นในฐานข้อมูล ขึ้นอยู่กับไดรเวอร์เฉพาะอย่างไร ทุกวันนี้ ไดรเวอร์จำนวนมากรองรับการตั้งค่านี้แล้ว ตรงกันข้ามกับเมื่อเร็วๆ นี้ นี่คือตัวอย่างบางส่วนที่ฉันรู้

สะพาน JDBC-ODBC

นี่เป็นหนึ่งในไดรเวอร์ที่ใช้บ่อยที่สุด บริดจ์จาก JDK 1.2 และเก่ากว่าสามารถกำหนดค่าได้อย่างง่ายดายเพื่อเข้ารหัสที่ต้องการ ทำได้โดยการเพิ่มคุณสมบัติ charSet เพิ่มเติมให้กับชุดของพารามิเตอร์ที่ส่งผ่านเพื่อเปิดการเชื่อมต่อกับฐาน ค่าดีฟอลต์คือ file.encoding สิ่งนี้ทำสิ่งนี้:

// สร้างการเชื่อมต่อ

ไดรเวอร์ Oracle 8.0.5 JDBC-OCI สำหรับ Linux

เมื่อได้รับข้อมูลจากฐานข้อมูล ไดรเวอร์นี้จะกำหนดการเข้ารหัส "ของมัน" โดยใช้ตัวแปรสภาพแวดล้อม NLS_LANG หากไม่พบตัวแปรนี้ จะถือว่าการเข้ารหัสเป็น ISO-8859-1 เคล็ดลับคือ NLS_LANG ควรเป็นตัวแปรสภาพแวดล้อม (ตั้งค่าด้วยคำสั่ง set) ไม่ใช่คุณสมบัติของระบบ Java (เช่น file.encoding) หากใช้ไดรเวอร์ภายในเอ็นจินเซิร์ฟเล็ต Apache + Jserv ตัวแปรสภาพแวดล้อมสามารถตั้งค่าได้ในไฟล์ jserv.properties:

wrapper.env = NLS_LANG = American_America.CL8KOI8R
ข้อมูลเกี่ยวกับสิ่งนี้ถูกส่งโดย Sergey Bezrukov ซึ่งต้องขอบคุณเขาเป็นพิเศษ

ไดรเวอร์ JDBC สำหรับการทำงานกับ DBF (zyh.sql.dbf.DBFDriver)

คนขับคนนี้เพิ่งเรียนรู้ที่จะทำงานกับตัวอักษรรัสเซีย แม้ว่าเขาจะรายงานโดย getPropertyInfo () ว่าเขาเข้าใจคุณสมบัติ charSet แต่ก็เป็นนิยาย (อย่างน้อยก็ในเวอร์ชันตั้งแต่ 30/07/2544) ในความเป็นจริง คุณสามารถปรับแต่งการเข้ารหัสโดยการตั้งค่าคุณสมบัติ CODEPAGEID สำหรับอักขระรัสเซีย มีสองค่า - "66" สำหรับ Cp866 และ "C9" สำหรับ Cp1251 ตัวอย่าง:

// พารามิเตอร์การเชื่อมต่อกับฐานคุณสมบัติ connInfo = คุณสมบัติใหม่ (); connInfo.put ("CODEPAGEID", "66"); // การเข้ารหัส Cp866 // สร้างการเชื่อมต่อฐานข้อมูลการเชื่อมต่อ = DriverManager.getConnection ("jdbc: DBF: / C: / MyDBFFiles", connInfo);
หากคุณมีไฟล์ DBF ในรูปแบบ FoxPro ไฟล์เหล่านั้นจะมีข้อมูลเฉพาะของตนเอง ความจริงก็คือ FoxPro จะบันทึก ID ของหน้ารหัสในส่วนหัวของไฟล์ (ไบต์ที่มีออฟเซ็ต 0x1D) ซึ่งใช้ในการสร้าง DBF เมื่อเปิดตาราง ไดรเวอร์จะใช้ค่าจากส่วนหัว ไม่ใช่พารามิเตอร์ "CODEPAGEID" (พารามิเตอร์ในกรณีนี้จะใช้เมื่อสร้างตารางใหม่เท่านั้น) ดังนั้น เพื่อให้ทุกอย่างทำงานได้อย่างถูกต้อง ไฟล์ DBF จะต้องสร้างด้วยการเข้ารหัสที่ถูกต้อง ไม่เช่นนั้นจะเกิดปัญหาขึ้น

MySQL (org.gjt.mm.mysql.Driver)

ด้วยไดรเวอร์นี้ ทุกอย่างก็ค่อนข้างง่ายเช่นกัน:

// พารามิเตอร์การเชื่อมต่อกับฐานคุณสมบัติ connInfo = Poperties ใหม่ (); connInfo.put ("ผู้ใช้" ผู้ใช้); connInfo.put ("รหัสผ่าน", ผ่าน); connInfo.put ("useUnicode", "จริง"); connInfo.put ("การเข้ารหัสอักขระ", "KOI8_R"); การเชื่อมต่อ conn = DriverManager.getConnection (dbURL, อุปกรณ์ประกอบฉาก);

InterBase (interbase.interclient.Driver)

สำหรับไดรเวอร์นี้ พารามิเตอร์ "charSet" ใช้งานได้:
// พารามิเตอร์การเชื่อมต่อกับฐานคุณสมบัติ connInfo = คุณสมบัติใหม่ (); connInfo.put ("ผู้ใช้", ชื่อผู้ใช้); connInfo.put ("รหัสผ่าน", รหัสผ่าน); connInfo.put ("charSet", "Cp1251"); // สร้างการเชื่อมต่อฐานข้อมูลการเชื่อมต่อ = DriverManager.getConnection (dataurl, connInfo);

อย่างไรก็ตาม อย่าลืมระบุการเข้ารหัสอักขระเมื่อสร้างฐานข้อมูลและตาราง สำหรับภาษารัสเซีย คุณสามารถใช้ค่า "UNICODE_FSS" หรือ "WIN1251" ตัวอย่าง:

สร้างฐานข้อมูล ′ E: ProjectHoldingDataBaseHOLDING.GDB ′ PAGE_SIZE 4096 ชุดอักขระเริ่มต้น UNICODE_FSS; สร้างตาราง RUSSIAN_WORD ("NAME1" VARCHAR (40) ชุดอักขระ UNICODE_FSS ไม่ใช่ NULL "NAME2" VARCHAR (40) ชุดอักขระ WIN1251 ไม่ใช่ NULL คีย์หลัก ("NAME1"));

มีข้อบกพร่องในเวอร์ชัน 2.01 ของ InterClient - คลาสทรัพยากรที่มีข้อความสำหรับภาษารัสเซียไม่ได้รับการคอมไพล์อย่างถูกต้อง เป็นไปได้มากที่นักพัฒนาจะลืมระบุการเข้ารหัสต้นทางเมื่อทำการคอมไพล์ มีสองวิธีในการแก้ไขข้อผิดพลาดนี้:

  • ใช้ interclient-core.jar แทน interclient.jar ในเวลาเดียวกันจะไม่มีแหล่งข้อมูลภาษารัสเซียและทรัพยากรภาษาอังกฤษจะถูกหยิบขึ้นมาโดยอัตโนมัติ
  • คอมไพล์ไฟล์ใหม่เป็น Unicode ปกติ การแยกวิเคราะห์ไฟล์คลาสเป็นงานที่ไม่เห็นคุณค่า ดังนั้นจึงควรใช้ JAD น่าเสียดายที่ JAD หากพบอักขระจากชุด ISO-8859-1 จะแสดงผลเป็นการเข้ารหัส 8 หลัก ดังนั้นคุณจะไม่สามารถใช้ตัวเข้ารหัส native2ascii มาตรฐานได้ - คุณต้องเขียนเอง (โปรแกรมถอดรหัส) หากคุณไม่ต้องการกังวลกับปัญหาเหล่านี้ คุณสามารถใช้ไฟล์สำเร็จรูปที่มีทรัพยากร (jar ที่แพทช์พร้อมไดรเวอร์ - interclient.jar แยกคลาสของทรัพยากร - interclient-rus.jar)

แต่ถึงแม้จะปรับไดรเวอร์ JDBC เป็นการเข้ารหัสที่ต้องการแล้ว ในบางกรณี คุณอาจประสบปัญหาได้ ตัวอย่างเช่น เมื่อพยายามใช้เคอร์เซอร์เลื่อน JDBC 2 ใหม่ที่ยอดเยี่ยมในบริดจ์ JDBC-ODBC จาก JDK 1.3.x คุณจะพบว่าตัวอักษรรัสเซียใช้งานไม่ได้ที่นั่น (เมธอด updateString ())

มีเรื่องเล็ก ๆ ที่เกี่ยวข้องกับข้อผิดพลาดนี้ เมื่อฉันค้นพบมันเป็นครั้งแรก (ภายใต้ JDK 1.3 rc2) ฉันลงทะเบียนกับ BugParade () เมื่อเบต้าแรกของ JDK 1.3.1 ออกมา จุดบกพร่องนี้ถูกตั้งค่าสถานะว่าได้รับการแก้ไขแล้ว ฉันดาวน์โหลดเบต้านี้แล้ว ทดสอบแล้ว - มันใช้งานไม่ได้ ฉันเขียนถึง Sun-sheep เกี่ยวกับเรื่องนี้ - ในการตอบกลับพวกเขาเขียนถึงฉันว่าการแก้ไขจะรวมอยู่ในรุ่นต่อๆ ไป โอเค ฉันคิดว่ารอก่อน เวลาผ่านไป รีลีส 1.3.1 ออกแล้ว และเบต้า 1.4 ในที่สุดฉันก็ใช้เวลาในการตรวจสอบ - มันใช้งานไม่ได้อีกครั้ง แม่ แม่ แม่ ... - เสียงสะท้อนก้องเป็นนิสัย หลังจากจดหมายโกรธถึง Sun พวกเขาแนะนำข้อผิดพลาดใหม่ () ซึ่งพวกเขามอบให้กับสาขาของอินเดียเพื่อแยกส่วน ชาวอินเดียเล่นซอกับรหัสและกล่าวว่าทุกอย่างได้รับการแก้ไขใน 1.4 beta3 ฉันดาวน์โหลดเวอร์ชันนี้ ใช้กรณีทดสอบภายใต้เวอร์ชันนี้ นี่คือผลลัพธ์ - ตามที่ปรากฏ beta3 ที่เผยแพร่บนไซต์ (รุ่น 84) ไม่ใช่ beta3 ที่มีการแก้ไขขั้นสุดท้าย (รุ่น 87) ตอนนี้พวกเขาสัญญาว่าการแก้ไขจะรวมอยู่ใน 1.4 rc1 ... โดยทั่วไปแล้วคุณเข้าใจ :-)

ตัวอักษรรัสเซียในแหล่งที่มาของโปรแกรม Java

ดังที่กล่าวไว้ โปรแกรมใช้ Unicode เมื่อดำเนินการ ไฟล์ต้นฉบับเขียนด้วยโปรแกรมแก้ไขทั่วไป ฉันใช้ Far คุณอาจจะมีบรรณาธิการที่คุณชื่นชอบ โปรแกรมแก้ไขเหล่านี้บันทึกไฟล์ในรูปแบบ 8 บิต ซึ่งหมายความว่าการใช้เหตุผลแบบเดียวกับข้างต้นจะมีผลกับไฟล์เหล่านี้เช่นกัน คอมไพเลอร์รุ่นต่างๆ ทำการแปลงอักขระแตกต่างกันเล็กน้อย JDK 1.1.x เวอร์ชันก่อนหน้าใช้การตั้งค่า file.encoding ซึ่งสามารถแทนที่ด้วยตัวเลือก -J ที่ไม่ได้มาตรฐาน ในเวอร์ชันที่ใหม่กว่า (ตามที่รายงานโดย Denis Kokarev - เริ่มตั้งแต่ 1.1.4) มีการแนะนำพารามิเตอร์ -encoding เพิ่มเติมซึ่งคุณสามารถระบุการเข้ารหัสที่ใช้ได้ ในคลาสที่คอมไพล์ สตริงจะแสดงในรูปแบบของ Unicode (แม่นยำกว่านั้น ในรูปแบบ UTF8) ที่แก้ไขแล้ว ดังนั้นสิ่งที่น่าสนใจที่สุดจึงเกิดขึ้นระหว่างการคอมไพล์ ดังนั้น สิ่งที่สำคัญที่สุดคือการค้นหาสิ่งที่เข้ารหัสซอร์สโค้ดของคุณ และระบุค่าที่ถูกต้องเมื่อทำการคอมไพล์ โดยค่าเริ่มต้น file.encoding ที่มีชื่อเสียงเหมือนกันจะถูกใช้ ตัวอย่างของการเรียกคอมไพเลอร์:

นอกจากการใช้การตั้งค่านี้แล้ว ยังมีอีกวิธีหนึ่งคือ - เพื่อระบุตัวอักษรในรูปแบบ "uXXXX" ซึ่งระบุรหัสอักขระ วิธีนี้ใช้ได้กับทุกเวอร์ชัน และคุณสามารถใช้ยูทิลิตี้มาตรฐานเพื่อรับโค้ดเหล่านี้ได้

หากคุณใช้ IDE ใด ๆ แสดงว่าอาจมีข้อบกพร่องของตัวเอง บ่อยครั้งที่ IDE เหล่านี้ใช้การเข้ารหัสเริ่มต้นสำหรับการอ่าน / บันทึกแหล่งที่มา ดังนั้นให้ใส่ใจกับการตั้งค่าภูมิภาคของระบบปฏิบัติการของคุณ นอกจากนี้ อาจมีข้อผิดพลาดที่ชัดเจน ตัวอย่างเช่น CodeGuide ระดับ IDE ที่ค่อนข้างดีไม่สามารถแยกแยะตัวอักษรรัสเซียตัวพิมพ์ใหญ่ "T" ได้ ตัววิเคราะห์โค้ดในตัวใช้จดหมายนี้เป็นเครื่องหมายอัญประกาศคู่ ซึ่งนำไปสู่ความจริงที่ว่าโค้ดที่ถูกต้องถูกมองว่าผิดพลาด คุณสามารถต่อสู้กับสิ่งนี้ (โดยแทนที่ตัวอักษร "T" ด้วยรหัส "u0422") แต่ไม่น่าพอใจ เห็นได้ชัดว่าบางแห่งใน parser มีการแปลงอักขระอย่างชัดเจนเป็นไบต์ (เช่น: byte b = (byte) c) ดังนั้นแทนที่จะใช้รหัส 0x0422 (รหัสของตัวอักษร "T") รหัสคือ 0x22 ( รหัสของอัญประกาศคู่)

JBuilder มีปัญหาอื่น แต่เกี่ยวข้องกับการยศาสตร์มากกว่า ความจริงก็คือใน JDK 1.3.0 ซึ่ง JBuilder ทำงานโดยค่าเริ่มต้น มีข้อบกพร่อง () เนื่องจากหน้าต่าง GUI ที่สร้างขึ้นใหม่เมื่อเปิดใช้งานจะรวมเค้าโครงแป้นพิมพ์โดยอัตโนมัติขึ้นอยู่กับการตั้งค่าภูมิภาคของระบบปฏิบัติการ เหล่านั้น. หากคุณมีการตั้งค่าภูมิภาคของรัสเซีย จะพยายามเปลี่ยนไปใช้เค้าโครงภาษารัสเซียอย่างต่อเนื่อง ซึ่งจะขัดขวางการเขียนโปรแกรม ไซต์ JBuilder.ru มีแพตช์สองสามตัวที่เปลี่ยนสถานที่ปัจจุบันใน JVM เป็น Locale.US แต่วิธีที่ดีที่สุดคือการอัปเกรดเป็น JDK 1.3.1 ซึ่งได้แก้ไขข้อผิดพลาดนี้แล้ว

ผู้ใช้ JBuilder มือใหม่อาจประสบปัญหาดังกล่าว - ตัวอักษรรัสเซียจะถูกบันทึกเป็นรหัส "uXXXX" เพื่อหลีกเลี่ยงปัญหานี้ ในกล่องโต้ตอบคุณสมบัติโปรเจ็กต์เริ่มต้น แท็บทั่วไป ในฟิลด์การเข้ารหัส ให้เปลี่ยนค่าเริ่มต้นเป็น Cp1251

หากคุณกำลังใช้สำหรับการคอมไพล์ไม่ใช่จาวามาตรฐาน แต่เป็นคอมไพเลอร์ตัวอื่น - ให้ความสนใจกับวิธีการแปลงอักขระ ตัวอย่างเช่น คอมไพเลอร์ IBM jikes บางเวอร์ชันไม่เข้าใจว่ามีการเข้ารหัสอื่นที่ไม่ใช่ ISO-8859-1 :-) มีเวอร์ชันที่ได้รับการแก้ไขในเรื่องนี้ แต่บ่อยครั้งที่การเข้ารหัสบางส่วนถูกเย็บไว้ที่นั่นด้วย - ไม่มีความสะดวกเช่นใน javac

JavaDoc

ในการสร้างเอกสาร HTML สำหรับซอร์สโค้ด จะใช้ยูทิลิตี้ javadoc ซึ่งรวมอยู่ในการแจกจ่าย JDK มาตรฐาน ในการระบุการเข้ารหัส มีพารามิเตอร์มากถึง 3 ตัว:

  • -encoding - การตั้งค่านี้ระบุการเข้ารหัสต้นทาง ค่าดีฟอลต์คือ file.encoding
  • -docencoding - การตั้งค่านี้ระบุการเข้ารหัสของไฟล์ HTML ที่สร้างขึ้น ค่าดีฟอลต์คือ file.encoding
  • -charset - การตั้งค่านี้ระบุการเข้ารหัสที่จะเขียนไปยังส่วนหัวของไฟล์ HTML ที่สร้างขึ้น ( ). เห็นได้ชัดว่ามันควรจะเหมือนกับการตั้งค่าก่อนหน้านี้ หากละเว้นการตั้งค่านี้ เมตาแท็กจะไม่ถูกเพิ่ม

ตัวอักษรรัสเซียในไฟล์คุณสมบัติ

วิธีการโหลดทรัพยากรใช้เพื่ออ่านไฟล์คุณสมบัติ ซึ่งทำงานในลักษณะเฉพาะ ที่จริงแล้ว วิธี Properties.load ใช้สำหรับการอ่าน ซึ่งไม่ได้ใช้ file.encoding (การเข้ารหัส ISO-8859-1 นั้นฮาร์ดโค้ดในแหล่งที่มา) ดังนั้นวิธีเดียวที่จะระบุตัวอักษรรัสเซียคือการใช้รูปแบบ "uXXXX" และอรรถประโยชน์

วิธีการ Properties.save ทำงานแตกต่างกันใน JDK 1.1 และ 1.2 ในเวอร์ชัน 1.1 มันเพียงแค่ทิ้ง high byte ดังนั้นมันจึงทำงานอย่างถูกต้องกับตัวอักษรภาษาอังกฤษเท่านั้น ใน 1.2 จะแปลงกลับเป็น "uXXXX" เพื่อให้ทำงานเหมือนวิธีการโหลด

หากไฟล์คุณสมบัติของคุณไม่ได้โหลดเป็นรีซอร์ส แต่เป็นไฟล์คอนฟิกูเรชันทั่วไป และคุณไม่พอใจกับพฤติกรรมนี้ มีทางเดียวเท่านั้นคือเขียนตัวโหลดของคุณเอง

ตัวอักษรรัสเซียใน Servlets

ฉันคิดว่า Servlets เดียวกันนี้มีไว้เพื่ออะไร ฉันคิดว่าคุณรู้ ถ้าไม่ ทางที่ดีควรอ่านเอกสารก่อน ที่นี่อธิบายลักษณะเฉพาะของการทำงานกับตัวอักษรรัสเซียเท่านั้น

แล้วคุณสมบัติมีอะไรบ้าง? เมื่อ Servlet ส่งการตอบกลับไปยังไคลเอนต์ มีสองวิธีในการส่งการตอบสนองนั้น — ผ่านวิธี OutputStream (getOutputStream ()) หรือวิธี PrintWriter (getWriter ()) ในกรณีแรก คุณกำลังเขียนอาร์เรย์ของไบต์ ดังนั้นวิธีการข้างต้นในการเขียนไปยังสตรีมจึงมีผลบังคับใช้ ในกรณีของ PrintWriter จะใช้ชุดการเข้ารหัส ไม่ว่าในกรณีใด คุณต้องระบุการเข้ารหัสที่ใช้เมื่อเรียกใช้เมธอด setContentType () อย่างถูกต้อง เพื่อให้สามารถแปลงอักขระในฝั่งเซิร์ฟเวอร์ได้ถูกต้อง คำสั่งนี้ต้องทำก่อนการเรียก getWriter () หรือก่อนการเขียนครั้งแรกไปยัง OutputStream ตัวอย่าง:

// ตั้งค่าการเข้ารหัสของการตอบสนอง // โปรดทราบว่าเอ็นจิ้นบางตัวไม่อนุญาต // ช่องว่างระหว่าง ';' และ 'ชุดอักขระ' response.setContentType ("ข้อความ / html; ชุดอักขระ = UTF-8"); PrintWriter out = response.getWriter (); // ดีบักเอาต์พุตของชื่อการเข้ารหัสที่จะตรวจสอบ out.println ("การเข้ารหัส:" + response.getCharacterEncoding ()); ... out.close (); )

คือการให้คำตอบกับลูกค้า น่าเสียดายที่พารามิเตอร์อินพุตไม่ง่ายนัก พารามิเตอร์อินพุตถูกเข้ารหัสโดยไบต์ของเบราว์เซอร์ตามประเภท MIME "application / x-www-form-urlencoded" ตามที่ Alexey Mendelev กล่าว เบราว์เซอร์เข้ารหัสตัวอักษรรัสเซียโดยใช้การเข้ารหัสที่ตั้งไว้ในปัจจุบัน และแน่นอนว่าไม่มีรายงานเกี่ยวกับเรื่องนี้ ตัวอย่างเช่น ในเวอร์ชัน JSDK ตั้งแต่ 2.0 ถึง 2.2 สิ่งนี้จะไม่ถูกตรวจสอบ แต่อย่างใด และการเข้ารหัสประเภทใดที่จะใช้สำหรับการแปลงขึ้นอยู่กับเอ็นจิ้นที่ใช้ เริ่มต้นด้วยข้อกำหนด 2.3 เป็นไปได้ที่จะตั้งค่าการเข้ารหัสสำหรับ javax.servlet.ServletRequest - เมธอด setCharacterEncoding () Resin และ Tomcat เวอร์ชันล่าสุดรองรับข้อกำหนดนี้แล้ว

ดังนั้น หากคุณโชคดีและคุณมีเซิร์ฟเวอร์ที่รองรับ Servlet 2.3 ทุกอย่างก็ค่อนข้างง่าย:

doPost โมฆะสาธารณะ (คำขอ HttpServletRequest การตอบสนอง HttpServletResponse) พ่น ServletException, IOException ( // การเข้ารหัสข้อความ request.setCharacterEncoding ("Cp1251"); ค่าสตริง = request.getParameter ("ค่า"); ...

มีความละเอียดอ่อนที่สำคัญอย่างหนึ่งในการใช้เมธอด request.setCharacterEncoding () - ต้องใช้ ก่อนการเรียกขอข้อมูลครั้งแรก (เช่น request.getParameter ()) หากคุณใช้ตัวกรองที่ประมวลผลคำขอก่อนที่จะมาถึงเซิร์ฟเล็ต มีโอกาสไม่ใช่ศูนย์ที่ตัวกรองตัวใดตัวหนึ่งอาจอ่านพารามิเตอร์บางตัวจากคำขอ (เช่น สำหรับการอนุญาต) และ request.setCharacterEncoding () ในเซิร์ฟเล็ตจะไม่ ทำงาน ...

ดังนั้นจึงถูกต้องตามหลักอุดมคติมากกว่าที่จะเขียนตัวกรองที่กำหนดการเข้ารหัสคำขอ ยิ่งไปกว่านั้น จะต้องเป็นลำดับแรกในกลุ่มตัวกรองใน web.xml

ตัวอย่างของตัวกรองดังกล่าว:

นำเข้า java.io *; นำเข้า java.util *; นำเข้า javax.servlet. *; นำเข้า javax.servlet.http. *; CharsetFilter คลาสสาธารณะใช้ตัวกรอง (// การเข้ารหัสการเข้ารหัสสตริงส่วนตัว init โมฆะสาธารณะ (การกำหนดค่า FilterConfig) พ่น ServletException ( // อ่านจาก configการเข้ารหัส = config.getInitParameter ("requestEncoding"); // ถ้าไม่ได้ติดตั้ง ให้ติดตั้ง Cp1251ถ้า (การเข้ารหัส == null) การเข้ารหัส = "Cp1251"; ) โมฆะสาธารณะ doFilter (คำขอ ServletRequest, การตอบสนอง ServletResponse, FilterChain ถัดไป) พ่น IOException, ServletException (request.setCharacterEncoding (การเข้ารหัส); next.doFilter (คำขอ, การตอบสนอง);) การทำลายโมฆะสาธารณะ () ())

และการกำหนดค่าใน web.xml:

ตัวกรองชุดอักขระ CharsetFilter ตัวกรองชุดอักขระ /*

หากคุณโชคไม่ดีและคุณมีเวอร์ชันเก่า คุณจะต้องบิดเบือนเพื่อให้ได้ผลลัพธ์:

    Russian Apache นำเสนอวิธีดั้งเดิมในการทำงานกับการเข้ารหัส - มีการอธิบายอย่างชัดเจนว่าเป็นอย่างไร

  • FOP

    แพ็คเกจ FOP ได้รับการออกแบบมาสำหรับการประมวลผลเอกสารตามมาตรฐาน XSL FO (Formating Objects) โดยเฉพาะอย่างยิ่ง ช่วยให้คุณสร้างเอกสาร PDF ตาม เอกสาร XML... แพ็คเกจ FOP ใช้ตัวประมวลผล Xalan XSLT ที่จับคู่กับ Xerces โดยค่าเริ่มต้นเพื่อแปลงจาก XML ดั้งเดิมเป็น FO ในการสร้างภาพสุดท้ายใน FOP คุณต้องเชื่อมต่อแบบอักษรที่รองรับตัวอักษรรัสเซีย นี่คือวิธีที่คุณสามารถทำได้สำหรับเวอร์ชัน 0.20.1:

    1. คัดลอกไฟล์ ttf จากไดเร็กทอรีระบบ Windows ไปยังไดเร็กทอรีย่อย conffonts (เช่น ใน c: fop-0.20.1conffonts) Arial ปกติ / ปกติ ปกติ / ตัวหนา ตัวเอียง / ปกติ และ ตัวเอียง / ตัวหนา ต้องใช้ไฟล์ arial.ttf, arialbd.ttf, ariali.ttf และ arialbi.ttf
    2. สร้างไฟล์คำอธิบายแบบอักษร (เช่น arial.xml) ในการดำเนินการนี้ สำหรับแต่ละฟอนต์ คุณต้องเรียกใช้คำสั่ง (สำหรับ Arial ปกติ / ปกติ ทั้งหมดในบรรทัดเดียว):
      java -cp.; c: fop-0.20.1uildfop.jar; c: fop-0.20.1libatik.jar; c: fop-0.20.1libxalan-2.0.0.jar; c: fop-0.20.1libxerces.jar; c: fop-0.20.1libjimi-1.0.jar org.apache.fop.fonts.apps.TTFReader fontsarial.ttf fontsarial.xml
    3. ใน FOP เพิ่มคำอธิบายของฟอนต์ด้วยตัวอักษรรัสเซียใน conf / userconfig.xml เช่น:
      Arial ปกติ / ตัวหนา ตัวเอียง / ปกติ และ ตัวเอียง / ตัวหนา ถูกเพิ่มในทำนองเดียวกัน
    4. เมื่อโทร FOP จาก บรรทัดคำสั่งหลังจาก org.apache.fop.apps.Fop เขียน -c c: fop-0.20.1confuserconfig.xml หากคุณต้องการใช้ FOP จากเซิร์ฟเล็ต คุณต้องใช้ในเซิร์ฟเล็ตหลังบรรทัด
      คนขับรถ= ไดรเวอร์ใหม่ ();
      เพิ่มบรรทัด:
      // ไดเร็กทอรีฟอนต์ (c: weblogicfonts) ถูกสร้างขึ้นเพื่อความสะดวกเท่านั้นสตริง userConfig = "แบบอักษร / userconfig.xml"; ไฟล์ userConfigFile = ไฟล์ใหม่ (userConfig); ตัวเลือกตัวเลือก = ตัวเลือกใหม่ (userConfigFile);
      จากนั้น ตำแหน่งของไฟล์ ttf ในไฟล์ userconfig.xml สามารถระบุให้สัมพันธ์กับรูทของแอปพลิเคชันเซิร์ฟเวอร์ โดยไม่ต้องระบุพาธสัมบูรณ์:
    5. ในไฟล์ FO (หรือ XML และ XSL) ก่อนใช้ฟอนต์ ให้เขียน:
      font-family = "Arial" font-weight = "bold" (ถ้าใช้ Arial ตัวหนา) font-style = "italic" (ถ้าใช้ Arial ตัวเอียง)

    อัลกอริทึมนี้ถูกส่งโดย Alexey Tyurin ซึ่งต้องขอบคุณเขาเป็นพิเศษ

    หากคุณใช้ตัวแสดงที่สร้างขึ้นใน FOP คุณต้องคำนึงถึงคุณสมบัติของมันด้วย โดยเฉพาะอย่างยิ่งแม้ว่าจะถือว่าจารึกในนั้นเป็น Russified แต่อันที่จริงแล้วมีข้อผิดพลาดเกิดขึ้น (ในเวอร์ชัน 0.19.0) ในการโหลดป้ายกำกับจากไฟล์ทรัพยากร แพ็คเกจ org.apache.fop.viewer.resources จะใช้ตัวโหลดของตัวเอง (คลาส org.apache.fop.viewer.LoadableProperties) การเข้ารหัสการอ่านได้รับการแก้ไขอย่างเข้มงวด (8859_1 เช่นเดียวกับในกรณีของ Properties.load ()) อย่างไรก็ตาม ไม่มีการรองรับประเภท "uXXXX" ฉันรายงานจุดบกพร่องนี้ให้นักพัฒนาทราบ พวกเขารวมการแก้ไขไว้ในแผนแล้ว

    เหนือสิ่งอื่นใด มีไซต์ที่ทุ่มเทให้กับ Russification of FOP (http://www.openmechanics.org/rusfop/) ที่นั่น คุณจะพบชุดการแจกจ่าย FOP ที่มีข้อผิดพลาดที่แก้ไขแล้วและเชื่อมต่อแบบอักษรรัสเซีย

    คอร์บา

    มาตรฐาน CORBA มีประเภทที่สอดคล้องกับประเภท Java String นี่คือประเภทสตริง ทุกอย่างเรียบร้อยดี แต่เซิร์ฟเวอร์ CORBA บางตัวไม่รองรับ