Thứ Sáu, 23 tháng 7, 2010

Mã hóa chuỗi bằng các kiểu mã hóa ký tự

? Bạn cần trao đổi dữ liệu dạng ký tự với các hệ thống sử dụng kiểu mã hóa khác với UTF-16 (kiểu mã hóa này được sử dụng bởi CRL).
--> Sử dụng lớp System.Text.Encoding và các lớp con của nó để chuyển đổi ký tự giữa các kiểu mã hóa khác nhau.
Unicode không phải là kiểu mã hóa duy nhất, cũng như UTF-16 không phải cách duy nhất biểu diễn ký tự Unicode. Khi ứng dụng cần trao đổi dữ liệu ký tự với các hệ thống bên ngoài (đặc biệt là các hệ thống cũ), dữ liệu cần phải được chuyển đổi giữa UTF-16 và kiểu mã hóa mà hệ thống đó hỗ trợ.
Lớp trừu tượng Encoding, và các lớp con của nó cung cấp các chức năng để chuyển ký tự qua lại giữa nhiều kiểu mã hóa khác nhau. Mỗi thể hiện của lớp con hỗ trợ việc chuyển đổi giữa UTF-16 và một kiểu mã hóa khác. Phương thức tĩnh Encoding.GetEncoding nhận vào tên hoặc số hiệu trang mã (code page number) của một kiểu mã hóa và trả về thể hiện của lớp mã hóa tương ứng.
Bảng 2.1 liệt kê một vài kiểu mã ký tự và số hiệu trang mã mà bạn phải truyền cho phương thức GetEncoding để tạo ra thể hiện của lớp mã hóa tương ứng. Bảng này cũng cung cấp các thuộc tính tĩnh của lớp Encoding đại diện cho phương thức GetEncoding tương ứng.

Bảng 2.1 Các lớp mã hóa ký tự
Kiểu mã hóa Lớp Sử dụng
ASCII ASCIIEncoding GetEncoding(20127)
hay thuộc tính ASCII
Mặc định (kiểu mã hóa hiện hành trên hệ thống) Encoding GetEncoding(0)
hay thuộc tính Default
UTF-7 UTF7Encoding GetEncoding(65000)
hay thuộc tính UTF7
UTF-8 UTF8Encoding GetEncoding(65001)
hay thuộc tính UTF8
UTF-16 (Big Endian) UnicodeEncoding GetEncoding(1201)
hay thuộc tính BigEndianUnicode
UTF-16 (Little Endian) UnicodeEncoding GetEncoding(1200)
hay thuộc tính Unicode
Windows OS Encoding GetEncoding(1252)

Sau khi đã lấy được đối tượng lớp Encoding hỗ trợ kiểu mã hóa thích hợp, sử dụng phương thức GetBytes để chuyển chuỗi nguồn (được mã hóa theo UTF-16) thành mảng kiểu byte chứa các ký tự được mã hóa theo kiểu cần chuyển, và sử dụng GetString để chuyển mảng byte thành chuỗi đích. Ví dụ dưới đây trình bày cách sử dụng một vài lớp mã hóa:
Code:
using System;
using System.IO;
using System.Text;

public class CharacterEncodingExample {

public static void Main() {

// Tạo file giữ các kết quả.
using (StreamWriter output = new StreamWriter("output.txt")) {

// Tạo và ghi ra file một chuỗi chứa ký hiệu của số PI.
string srcString = "Area = \u03A0r^2";
output.WriteLine("Source Text : " + srcString);

// Ghi các byte được mã hóa theo UTF-16
// của chuỗi nguồn ra file.
byte[] utf16String = Encoding.Unicode.GetBytes(srcString);
output.WriteLine("UTF-16 Bytes: {0}",
BitConverter.ToString(utf16String));

// Chuyển chuỗi nguồn được mã hóa theo UTF-16
// thành UTF-8 và ASCII
byte[] utf8String = Encoding.UTF8.GetBytes(srcString);
byte[] asciiString = Encoding.ASCII.GetBytes(srcString);

// Ghi mảng các byte được mã hóa theo UTF-8 và ASCII ra file.
output.WriteLine("UTF-8 Bytes: {0}",
BitConverter.ToString(utf8String));
output.WriteLine("ASCII Bytes: {0}",
BitConverter.ToString(asciiString));

// Chuyển các byte được mã hóa theo UTF-8 và ASCII
// thành chuỗi được mã hóa theo UTF-16 và ghi ra file.
output.WriteLine("UTF-8 Text : {0}",
Encoding.UTF8.GetString(utf8String));
output.WriteLine("ASCII Text : {0}",
Encoding.ASCII.GetString(asciiString));

// Ghi dữ liệu xuống file và đóng file.
output.Flush();
output.Close();
}
}
}
Chạy CharacterEncodingExample sẽ tạo ra file output.txt. Mở file này trong một trình soạn thảo có hỗ trợ Unicode, bạn sẽ thấy kết quả như sau:
Code:
Source Text : Area = Πr^2
UTF-16 Bytes: 41-00-72-00-65-00-61-00-20-00-3D-00-20-00-A0-03-72-00-5E-00-32-00
UTF-8 Bytes: 41-72-65-61-20-3D-20-CE-A0-72-5E-32
ASCII Bytes: 41-72-65-61-20-3D-20-3F-72-5E-32
UTF-8 Text : Area = Πr^2
ASCII Text : Area = ?r^2
Chú ý rằng, nếu sử dụng UTF-16 thì mỗi ký tự được mã hóa bởi 2 byte, nhưng vì hầu hết các ký tự đều là ký tự chuẩn nên byte cao là 0 (nếu sử dụng little-endian thì byte thấp viết trước). Do đó, hầu hết các ký tự đều được mã hóa bởi những số giống nhau trong ba kiểu mã hóa, ngoại trừ ký hiệu PI được mã hóa khác (được in đậm trong kết quả ở trên). Để mã hóa PI cần 2 byte, đòi hỏi này được UTF-8 hỗ trợ nên thể hiện được Π, trong khi đó ASCII chỉ sử dụng một byte nên thay PI bằng mã 3F, đây là mã của dấu hỏi .
+ Nếu chuyển các ký tự Unicode sang ASCII hoặc một kiểu mã hóa khác thì có thể mất dữ liệu. Bất kỳ ký tự Unicode nào có mã ký tự không biểu diễn được trong kiểu mã hóa đích sẽ bị bỏ qua khi chuyển đổi.
Lớp Encoding cũng cung cấp phương thức tĩnh Covert để đơn giản hóa việc chuyển một mảng byte từ kiểu mã hóa này sang kiểu mã hóa khác không phải qua trung gian UTF-16. Ví dụ, dòng mã sau chuyển trực tiếp các byte trong mảng asciiString từ ASCII sang UTF-8:
Code:
byte[] utf8String = Encoding.Convert(Encoding.ASCII, Encoding.UTF8,
asciiString);

0 nhận xét:

Đăng nhận xét