Chương 2 : Thao tác D liu
Hu hết các ng dng đều cn thao tác trên mt loi d liu nào đó. Microsoft .NET
Framework cung cp nhiu k thut để đơn gin hóa hay nâng cao hiu qu các thao tác
d liu thông dng. Chương này s đề cp các k thut sau:
Thao tác chui mt cách hiu qu (mc 2.1).
Mô t các kiu d liu cơ s bng các kiu mã hóa khác nhau (mc 2.2, 2.3, và 2.4).
S dng biu thc chính quy để xác nhn tính hp l và thao tác chui (mc 2.5 và
2.6).
Làm vic vi ngày và gi (mc 2.7 và 2.8).
Làm vic vi mng và tp hp (mc 2.9, 2.10, và 2.11).
Tun t hóa trng thái đối tượng và lưu nó vào file (mc 2.12).
1.1 Thao tác chui mt cách hiu qu
V
V
Bn cn thao tác trên ni dung ca mt đối tượng String và tránh chi phí ca
vic t động to các đối tượng String mi do tính không đổi ca đối tượng
String.
#
#
S dng lp System.Text.StringBuilder để thc hin các thao tác, sau đó
chuyn kết qu thành String bng phương thc StringBuilder.ToString.
Các đối tượng String trong .NET là không đổi, nghĩa là mt khi đã được to thì chúng
không th b thay đổi. Ví d, nếu bn to mt String bng cách ni mt s ký t hoc
chui, thì khi thêm mt phn t mi vào cui String hin có, b thc thi s to ra mt
String mi cha kết qu (ch không phi String cũ b thay đổi). Do đó s ny sinh chi phí
đáng k nếu ng dng ca bn thường xuyên thao tác trên String.
Lp StringBuilder khc phc vn đề này bng cách cung cp mt b đệm ký t, và cho
phép thao tác trên ni dung ca nó mà b thc thi không phi to đối tượng mi để cha
kết qu sau mi ln thay đổi. Bn có th to mt đối tượng StringBuilder rng hoc được
khi to là ni dung ca mt String hin có. Sau đó, thao tác trên ni dung ca
StringBuilder này bng các phương thc np chng (cho phép bn chèn, thêm dng chui
ca các kiu d liu khác nhau). Cui cùng, gi StringBuilder.ToString để chuyn ni
dung hin ti ca StringBuilder thành mt String.
Khi bn thêm d liu mi vào chui, có hai thuc tính quan trng nh hưởng đến hot
động ca StringBuilder là Capacity và Length. Capacity mô t kích thước ca b đệm
StringBuilder, còn Length mô t kích thước ca chui ký t trong b đệm. Nếu vic thêm
d liu mi vào StringBuilder làm kích thước chui (Length) vượt quá kích thước b
đệm (Capacity) thì StringBuilder s cp phát b đệm mi để cha chui. Nếu thiếu cn
thn, vic cp phát b đệm này có th ph định li ích ca vic s dng StringBuilder.
Do đó, nếu biết chính xác kích thước ca chui, hoc biết kích thước ti đa ca chui,
bn có th tránh vic cp phát b đệm quá mc cn thiết bng cách thiết lp thuc tính
Capacity hoc ch định kích thước b đệm lúc to StringBuilder. Khi thiết lp các thuc
tính Capacity và Length, cn chú ý các đim sau:
Nếu bn thiết lp giá tr Capacity nh hơn giá tr Length, thuc tính Capacity s ném
ngoi l System.ArgumentOutOfRangeException.
Nếu bn thiết lp giá tr Length nh hơn kích thước ca chui hin có trong b đệm,
chui s b ct bt phn ln hơn.
Nếu bn thiết lp giá tr Length ln hơn kích thước ca chui, b đệm s được "lp"
thêm các khong trng cho bng vi Length. Vic thiết lp giá tr Length ln hơn
giá tr Capacity s t động điu chnh Capacity cho bng vi Length.
Phương thc ReverseString dưới đây minh ha cách s dng lp StringBuilder để đảo
mt chui. Nếu không s dng lp StringBuilder để thc hin thao tác này thì s tn chi
phí đáng k, đặc bit khi chui ngun dài. Vic khi to StringBuilder vi kích thước
bng chui ngun bo đảm không cn phi cp phát li b đệm trong quá trình đảo chui.
public static string ReverseString(string str) {
// Kim tra các trường hp không cn đảo chui.
if (str == null || str.Length == 1) {
return str;
}
// To mt StringBuilder vi sc cha cn thiết.
System.Text.StringBuilder revStr =
new System.Text.StringBuilder(str.Length);
// Duyt ngược chui ngun tng ký t mt
// và thêm tng ký t đọc được vào StringBuilder.
for (int count = str.Length-1; count > -1; count--) {
revStr.Append(str[count]);
}
// Tr v chui đã được đảo.
return revStr.ToString();
}
1.2hóa chui bng các kiu mã hóa ký t
V
V
Bn cn trao đổi d liu dng ký t vi các h thng s dng kiu mã hóa khác
vi UTF-16 (kiu mã hóa này được s dng bi CRL).
#
#
S dng lp System.Text.Encoding và các lp con ca nó để chuyn đổi ký t
gia các kiu mã hóa khác nhau.
Unicode không phi là kiu mã hóa duy nht, cũng như UTF-16 không phi cách duy
nht biu din ký t Unicode. Khi ng dng cn trao đổi d liu ký t vi các h thng
bên ngoài (đặc bit là các h thng cũ), d liu cn phi được chuyn đổi gia UTF-16
kiu mã hóa mà h thng đó h tr.
Lp tru tượng Encoding, và các lp con ca nó cung cp các chc năng để chuyn ký t
qua li gia nhiu kiu mã hóa khác nhau. Mi th hin ca lp con h tr vic chuyn
đổi gia UTF-16 và mt kiu mã hóa khác. Phương thc tĩnh Encoding.GetEncoding
nhn vào tên hoc s hiu trang mã (code page number) ca mt kiu mã hóa và tr v
th hin ca lp mã hóa tương ng.
Bng 2.1 lit kê mt vài kiu mã ký t và s hiu trang mã mà bn phi truyn cho
phương thc GetEncoding để to ra th hin ca lp mã hóa tương ng. Bng này cũng
cung cp các thuc tính tĩnh ca lp Encoding đại din cho phương thc GetEncoding
tương ng.
Bng 2.1 Các lp mã hóa ký t
Kiu mã hóa Lp S dng
ASCII ASCIIEncoding GetEncoding(20127)
hay thuc tính ASCII
Mc định (kiu mã hóa
hin hành trên h thng) Encoding GetEncoding(0)
hay thuc tính Default
UTF-7 UTF7Encoding GetEncoding(65000)
hay thuc tính UTF7
UTF-8 UTF8Encoding GetEncoding(65001)
hay thuc tính UTF8
UTF-16 (Big Endian) UnicodeEncoding GetEncoding(1201)
hay thuc tính BigEndianUnicode
UTF-16 (Little Endian) UnicodeEncoding GetEncoding(1200)
hay thuc tính Unicode
Windows OS
Encoding GetEncoding(1252)
Sau khi đã ly được đối tượng lp Encoding h tr kiu mã hóa thích hp, s dng
phương thc GetBytes để chuyn chui ngun (đưc mã hóa theo UTF-16) thành mng
kiu byte cha các ký t được mã hóa theo kiu cn chuyn, và s dng GetString để
chuyn mng byte thành chui đích. Ví d dưới đây trình bày cách s dng mt vài lp
mã hóa:
using System;
using System.IO;
using System.Text;
public class CharacterEncodingExample {
public static void Main() {
// To file gi các kết qu.
using (StreamWriter output = new StreamWriter("output.txt")) {
// To và ghi ra file mt chui cha ký hiu ca s PI.
string srcString = "Area = \u03A0r^2";
output.WriteLine("Source Text : " + srcString);
// Ghi các byte được mã hóa theo UTF-16
// ca chui ngun ra file.
byte[] utf16String = Encoding.Unicode.GetBytes(srcString);
output.WriteLine("UTF-16 Bytes: {0}",
BitConverter.ToString(utf16String));
// Chuyn chui ngun đượ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 mng 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));
// Chuyn các byte được mã hóa theo UTF-8 và ASCII
// thành chui đượ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 liu xung file và đóng file.
output.Flush();
output.Close();
}
}
}