C# - A System.Text névtér karakterkódolást végző osztályai

forráskód letöltése
A .NET-ben karakterláncaink különböző szempont szerint kódolhatók. Ennek érdekében a fejlesztők egy egész névteret hoztak létre, melynek neve System.Text. A névtérben megtalálhatjuk a különböző szabványokat reprezentáló osztályokat, mint amilyen az ASCIIEncoding, vagy a UnicodeEncoding osztály. Cikkünkben egy átfogó képet igyekszünk nyújtani erről a névtérről, osztályainak többségével pedig egy-egy gyakorlati példát is prezentálunk.
A System.Text névtér osztályai abban különböznek egymástól, hogy minden osztály egy-egy szabványt képvisel, vagyis amennyiben a karaktereinket egy bizonyos szabvány szerint – például mert a kommunikációs közeg ezt kívánja meg – kódolni kívánjuk, akkor az adott osztály metódusát kell meghívnunk, és generálhajuk a karaktereink adott szabvány szerinti bájtfolyam-értékét.
A következőkben minden kódoló/dekódoló osztályt megvizsgálunk, bemutatva a jellemző metódusaikat használat közben.
ASCIIEncoding osztály
Az osztály metódusainak segítségével képesek vagyunk Unicode karaktereinket ASCII karakterekké konvertálni. A konverzió 7-bites ASCII konverziót jelent, melynek nagy hátránya, hogy az egyes bájtok csak 0 és 127 értéket vehetnek fel. Ez a korlátozás nem teszi lehetővé a nemzetközi rendszerek együttműködését.
Az Unicode formátumban tárolt értékek ASCII formátumban történő tárolása adatvesztést okoz, hiszen az osztály a tartományon kívül eső értékeket a 63-as értéket képviselő „?” karakterrel helyettesíti.
Az osztály legjellemzőbben használt metódusai a következők:
GetByteCount
Osztály: ASCIIEncoding
public override int GetByteCount(
string chars
);
A metódus segítségével a paraméterként kapott karakterlánc, vagy a metódus másik változata – a karaktertömb esetén meghatározhatjuk, hogy a kódolás után milyen méretű bájttömbre van szükség az adathalmaz tárolásához.
Paraméterek
string chars
A kódolandó karakterlánc.
Visszatérési érték
A bájttömb mérete.
A GetBytes metódusnak két változata van, melyek közül az egyik a paraméterként kapott karakterlánc, míg a másik egy karaktertömb karaktereit kódolja és tárolja egy bájttömbben, melyet szintén paraméterként adunk át.
GetBytes
Osztály: ASCIIEncoding
public override int GetBytes(
char[] chars,
int charIndex,
int charCount,
byte[] bytes,
int byteIndex
);
A konverziót végző metódus.
Paraméterek
char[] chars
A kódolandó karaktertömb.
int charIndex
A tömb első eleme, mely legyen része a kódolt halmaznak.
int charCount
A karakterek száma, melyek kerüljenek kódolásra.
byte[] bytes
A feltöltendő bájttömb.
int byteIndex
A feltöltendő tömb azon rekeszének indexe, ahonnan a kódolt adatok tárolása kezdődjön.
Visszatérési érték
A tároló bájttömb mérete.
GetCharCount
Osztály: ASCIIEncoding
public override int GetCharCount(
byte[] bytes,
int index,
int count
);
A metódus megadja, hogy a paraméterként átadott bájttömbben tárolt bináris érték hány darab karakternek felel meg a dekódolás után.
Paraméterek
byte[] bytes
A bemeneti bájttömb.
int index
A bájttömb első bájtjának indexe, mely bekerül a kimeneti adathalmazba.
int count
A bájtok száma, melyek részei lesznek a kimeneti halmaznak.
Visszatérési érték
Az eredményhalmaz karaktereinek száma.
GetChars
Osztály: ASCIIEncoding
public override int GetChars(
byte[] bytes,
int byteIndex,
int byteCount,
char[] chars,
int charIndex
);
A metódus segítségével a kódolt adatokat, melyeket egy bájttömbben adunk meg, Unicode karaktertömbbé dekódolja.
Paraméterek
byte[] bytes
A kódolt információ bájttömbje.
int byteIndex
A bájttömb első bájtjának indexe, mely bekerül a kimeneti adathalmazba.
int byteCount
A bájtok száma, melyek részei lesznek a kimeneti halmaznak.
char[] chars
Az eredményt tároltó karaktertömb.
int charIndex
A kimeneti halmaz kezdő indexe a tömbben.
Visszatérési érték
A kimeneti karaktertömb elemszáma.
GetString
Osztály: ASCIIEncoding
public override string GetString(
byte[] bytes
);
A metódus a megadott bájttömböt karaktertömbbé konvertálja.
Paraméterek
byte[] bytes
A konvertálandó bájttömb.
Visszatérési érték
A bájttömb értéke karakterlánc formájában.
Az ASCIIEncoding osztály használata igen egyszerű, a példa-alkalmazásban az első fül alatt láthatunk használatára egy mintát. A KÓDOLÁS gomb megnyomásával egy bájttömbben tároljuk el a karakterláncot, melynek elemeit „[” és „]” jelek közt megjelenítjük a szövegmezőben. A DEKÓDOLÁS gomb segítségével pedig a bájttömb elemeit alakítjuk vissza Unicode karakterlánccá, mely természetesen (!) értékvesztéssel jár. A különleges karaktereket „?” karakterrel helyettesíti az osztály.
A műveletek előtt példányosítjuk az osztályt.
private ASCIIEncoding ae = new ASCIIEncoding();
A következő lépés, hogy a karakterláncot egy bájttömbben helyezzük el.
ASCIIBytes = ae.GetBytes(textBox1.Text);
A bájtokat elhelyezzük a szövegmezőben.
foreach (byte b in ASCIIBytes) 
{
  textBox2.Text += "[" + b + "]";        
}
Dekódoláskor a GetString metódust használjuk a bájttömb visszaalakításához.
textBox3.Text = ae.GetString(ASCIIBytes);
UnicodeEncoding osztály
Az osztály segítségével az Unicode karaktereket konvertálhatjuk UTF-16 (Unicode Transformation Format, 16 bites) karakterekké. A kódolás lényege, hogy minden karakter két bájton tárolódik. A két kódolt bájt BIG ENDIAN (legértékesebb helyi értékű bit kerül előre) vagy LITTLE ENDIAN (a legértéktelenebb helyi értékű bit kerül előre) bájtsorrendben tárolódnak, attól függően, hogy milyen számítógép-architektúrán kell ezt éppen használni.
A 16-bites tároláskor egy két-bájtos érték kerül a tárolt információ elejére azt jelezve, hogy éppen melyik bájtsorrend alkalmazható olvasáskor. Megállapodás szerint a bájtsorrend BIG ENDIAN, amennyiben a két bájt értéke hexadecimális 0xFEFF, és LITTLE ENDIAN, ha a két bájt értéke hexadecimális 0xFFFE.
Az osztály konstruktorának egyik változata esetén meg lehet adni, hogy milyen bájtsorrend érvényesüljön a tároláskor. Vizsgáljuk meg, hogy miként.
UnicodeEncoding
Osztály: UnicodeEncoding
public UnicodeEncoding(
bool bigEndian,
bool byteOrderMark
);
Létrejön egy példány az UnicodeEncoding osztályból.
Paraméterek
bool bigEndian
Amennyiben a logikai érték TRUE, az alkalmazott bájtsorrend BIG ENDIAN, ellenkező esetben LITTLE ENDIAN.
bool byteOrderMark
Amennyiben a logikai értéke TRUE, a tárolt információ tartalmazza a bájtsorrendre vonatkozó kétbájtos információt, míg FALSE esetén nem tartalmazza.
A következőkben megvizsgáljuk, hogy milyen metódusai érhetők el az osztálynak. Deklarációkat csak abban az esetben adunk közre, amikor eltérés tapasztalható az ASCIIEncoding osztály metódusainak deklarációjában.
Az osztály GetByteCount metódusa segítségével a paraméterként kapott karakterlánc - vagy a metódus másik változata esetén a karaktertömb - esetén meghatározhatjuk, hogy a kódolás után milyen méretű bájttömbre van szükség az adathalmaz tárolásához.
A GetBytes metódus két változata itt kiegészült egy harmadikkal, melynek egy karakterláncot kell átadni, és visszaadja az azt reprezentáló bájttömböt.
GetBytes
Osztály: UnicodeEncoding
public override byte[] GetBytes(
string s
);
A konverziót végző metódus.
Paraméterek
string s
A bemeneti karakterlánc.
Visszatérési érték
A bájttömb, melyben a karakterek két bájton tárolódnak.
Az osztály rendelkezik egy GetPeamble nevű metódussal, mely nem található meg az ASCIIEncoding osztályban.
GetPreamble
Osztály: UnicodeEncoding
public override byte[] GetPreamble();
Amennyiben az osztályt a paraméteres konstruktorral hoztuk létre, és a második paraméter TRUE értékű, akkor a metódussal lekérdezhető a bájtsorrendre utaló két-bájtos érték (0xFFFE, vagy 0xFEFF).
Visszatérési érték
Az eredmény-bájtok.
A mellékelt példában csak példányosítottuk az osztályt, és a KÓDOLÁS gomb megnyomásával konvertáljuk a karakterláncot UTF-16 formátumba.
UnicodeEncoding ue = new UnicodeEncoding();
...
UnicodeBytes = ue.GetBytes(textBox6.Text);
A bájtokat a „[” és a „]” karakterek között megjelenítjük a másik szövegmezőben.
foreach (byte b in UnicodeBytes) 
{
  textBox5.Text += "[" + b + "]";
}
A DEKÓDOLÁS gomb segítségével pedig visszaalakíthatjuk a bájttömböt karakterlánccá.
textBox4.Text = ue.GetString(UnicodeBytes);
UTF7Encoding osztály
Az osztály segítségével Unicode karaktereket konvertálhatunk át 7-bites karakterekké (UTF-7, UCS Transformation Format). A szabvány minden Unicode karaktert támogat, eredetileg az e-mail üzenetek átvitelére fejlesztették, a US-ASCII szöveges üzenetek számára.
Az osztály GetByteCount, GetBytes, GetCharCount és GetChars metódusainak deklarációja és használata megegyezik a korábbi deklarációkkal, és használati módokkal, csupán a szabvány változik. De ez a nagyszerű a .NET rendszerben, hogy elegendő egy deklarációt fejben tartani.
UTF8Encoding osztály
Az osztály segítségével Unicode karaktereket konvertálhatunk át 8-bites karakterekké (UTF-8, UCS Transformation Format). Az Unicode karakterek változatos bit-számú bájton tárolódhatnak, a tárolás legoptimálisabb az ASCII kódtábla alsó 127 eleme esetén.
Az osztály paraméteres konstruktora esetén van lehetőségünk megadni, hogy a kódolt információhalmaz tartalmazza-e az Unicode karakterek bájtsorrendjét megadó előtag UTF-8 megfelelőjét, illetve azt, hogy nem megfelelő bájtsorrend esetén generálódjon-e kivétel.
UTF8Encoding
Osztály: UTF8Encoding
public UTF8Encoding(
bool encoderShouldEmitUTF8Identifier,
bool throwOnInvalidBytes
);
Konstruktor.
Paraméterek
bool encoderShouldEmitUTF8Identifier
TRUE esetén megjelenik a kimenetben a bájtsorrendet jelző előtag, FALSE esetén nem.
bool throwOnInvalidBytes
TRUE esetén kivétel keletkezik abban az esetben, ha nem megfelelő kódolást észlel az algoritmus.
Az osztály GetByteCount, GetBytes, GetCharCount és GetChars metódusai itt is a fentiekhez hasonlóan használhatók.
Encoding osztály
Míg a névtér eddigi osztályai egy-egy szabvány megvalósítását tartalmazták, addig az Encoding osztály reprezentálja a kódolási algoritmusok valamennyi válfaját, ez a többi osztály őse. Az osztály property-jei segítségével mindegyik kódolási formát elérhetjük.
Vizsgáljuk meg az osztály metódusait.
GetEncoder
Osztály: Encoding
public virtual Encoder GetEncoder();
Lekérdezhetjük a kódolási algoritmust reprezentáló objektumot.
Visszatérési érték
Encoder típusú objektum, mely csak így hozható létre. Ezt követően van lehetőség meghívni az objektum metódusait, melyekkel kódolhatjuk az adott karakterláncot.
GetDecoder
Osztály: Encoding
public virtual Decoder GetDecoder();
Lekérdezhetjük a dekódolót reprezentáló objektumot.
Visszatérési érték
Az objektum metódusainak meghívásával tudjuk a bájtfolyamot újra karakterlánccá konvertálni.
A GetEncoding metódus két változatával hozhatunk létre Encoding objektumokat. Ekkor a platform által támogatott kódlap nevét, vagy számát kell paraméterként megadnunk.
GetEncoding
Osztály: Encoding
public static Encoding GetEncoding(
int codepage
);
A metódus létrehoz egy példányt az osztályból.
Paraméterek
int codepage
Kódlap száma, például:
Encoding enc = Encoding.GetEncoding(1252);
Visszatérési érték
Encoding objektum.
GetEncoding
Osztály: Encoding
public static Encoding GetEncoding(
string name
);
Létrehoz egy példányt az Encoding osztályból. Lássunk használatára egy példát:
Encoding enc = Encoding.GetEncoding("shift-jis");
Paraméterek
string name
Kódlap neve. Az osztály a következő kódlapokat támogatja:
Kódlap száma Megnevezése
1200 "UTF-16LE", "utf-16", "ucs-2", "unicode", vagy "ISO-10646-UCS-2"
1201 "UTF-16BE" vagy "unicodeFFFE"
1252 "windows-1252"
65000 "utf-7", "csUnicode11UTF7", "unicode-1-1-utf-7", "unicode-2-0-utf-7", "x-unicode-1-1-utf-7", vagy "x-unicode-2-0-utf-7"
65001 "utf-8", "unicode-1-1-utf-8", "unicode-2-0-utf-8", "x-unicode-1-1-utf-8", vagy "x-unicode-2-0-utf-8"
20127 "us-ascii", "us", "ascii", "ANSI_X3.4-1968", "ANSI_X3.4-1986", "cp367", "csASCII", "IBM367", "iso-ir-6", "ISO646-US", vagy "ISO_646.irv:1991"
54936 "GB18030"
Visszatérési érték
Encoding objektum.
Az osztály GetByteCount, GetBytes, GetCharCount, GetChars és GetString metódusai itt is a fentiekhez hasonlóan használhatók.
A példában az osztály segítségével az UTF-8 szabvány szerinti kódolást próbálhatjuk ki. Ennek érdekében létrehoztunk egy példányt a megfelelő módon.
Encoding enc = Encoding.UTF8;
A KÓDOLÁS gomb megnyomásakor a kapott objektum GetBytes metódusát felhasználva bájttömbbe töltjük kódolva a karakterláncot.
EncoderBytes = enc.GetBytes(textBox12.Text);
A bájtok értékét itt is megjelenítjük a szövegmezőben.
foreach(byte b in EncoderBytes)
{
  textBox11.Text += "[" + b + "]";
}
Dekódoláskor lekérdezzük az objektum dekódoló objektumát.
Decoder der = enc.GetDecoder();
Létrehozunk egy karaktertömböt a karakterek tárolására.
char[] chars = new char[der.GetCharCount(EncoderBytes,0,EncoderBytes.Length)];
A bájttömb elemeit betöltjük ebbe a karaktertömbbe.
der.GetChars(EncoderBytes,0,EncoderBytes.Length,chars,0);
Majd megjelenítjük azt a szövegmezőben.
foreach(char c in chars)
{
  textBox10.Text += c.ToString();
}