"Hallo Amigo!"

"Nu is het tijd voor een ander interessant onderwerp: coderingen."

"Misschien heb je al ergens gehoord dat elk teken een code (nummer) heeft. Daarom kan het tekentype zowel symbolen als cijfers vertegenwoordigen."

"De code voor de letter 'A' in het Engelse alfabet is bijvoorbeeld 65. 'B' is 66, 'C' is 67, enzovoort. Er zijn unieke codes voor hoofdletters, kleine letters, Cyrillische letters, Chinese karakters (ja, heel veel codes), cijfers en verschillende symbolen. Kortom, er is een code voor praktisch alles wat je een karakter zou noemen."

"Dus elke letter en elk teken komt overeen met een cijfer?"

"Precies."

"Een teken kan worden omgezet in een getal en een getal in een teken. Java ziet over het algemeen geen verschil tussen beide:"

char c = 'A'; //The code (number) for 'A' is 65
c++; //Now c contains the number 66, which is the code for 'B'

"Interessant."

"Dus een codering is een set symbolen en de bijbehorende set codes. Maar er is niet slechts één codering uitgevonden - er zijn er nogal wat. Pas later werd een algemene universele codering, Unicode, uitgevonden."

"Maar hoeveel universele standaarden er ook worden uitgevonden, niemand heeft haast om de oude los te laten. En dan gebeurt alles zoals in deze cartoon:"

Tekencoderingen - 1

"Stel je voor dat Vincent en Nick besluiten om hun eigen coderingen te maken."

"Hier is de codering van Vincent:"
Tekencoderingen - 2

"En hier is de codering van Nick:"
Tekencoderingen - 3

"Ze gebruiken zelfs dezelfde karakters, maar de codes voor de karakters zijn anders."

"Wanneer de string 'ABC-123' naar een bestand wordt geschreven met behulp van Vincent's codering, krijgen we de volgende reeks bytes:"
Tekencoderingen - 4

"En nu wil een ander programma dat de codering van Nick gebruikt het bestand lezen:"

"Dit is wat er zal staan: «345-IJK»."

"En het ergste is dat coderingen meestal nergens in bestanden worden opgeslagen, dus ontwikkelaars moeten raden."

"Nou, hoe raden ze ze?"

"Dat is een ander onderwerp. Maar ik wil uitleggen hoe je met coderingen moet werken. Zoals je al weet, is de grootte van een teken in Java twee bytes. En Java Strings gebruiken het Unicode-formaat."

"Maar met Java kun je een string omzetten in een set bytes in elke codering die het kent. De String-klasse heeft hiervoor speciale methoden. Java heeft ook een speciale Charset-klasse die een specifieke codering beschrijft."

1) Hoe krijg ik een lijst met alle coderingen die Java ondersteunt?

"Daarvoor is een speciale statische methode genaamd availableCharsets. "Deze methode retourneert een reeks paren (coderingsnaam, object dat de codering beschrijft):"

SortedMap<String,Charset> charsets = Charset.availableCharsets();

"Elke codering heeft een unieke naam. Hier zijn er een paar: UTF-8, UTF-16, Windows-1251, KOI8-R,..."

2) Hoe krijg ik de huidige actieve codering (Unicode)?

" Daarvoor is een speciale methode genaamd defaultCharset .

Charset currentCharset = Charset.defaultCharset();

3) Hoe converteer ik een string naar een specifieke codering?

"In Java kun je een string converteren naar een byte-array in elke codering die Java kent:"

Methode Voorbeeld
byte[] getBytes()
String s = "Good news, everyone!";
byte[] buffer = s.getBytes()
byte[] getBytes(Charset charset)
String s = "Good news, everyone!";
Charset koi8 = Charset.forName("KOI8-R");
byte[] buffer = s.getBytes(koi8);
byte[] getBytes(String charsetName)
String s = "Good news, everyone!";
byte[] buffer = s.getBytes("Windows-1251")

4) Hoe converteer ik een byte-array die ik uit een bestand heb gelezen naar een string, als ik weet wat de codering ervan in het bestand was?

"Dit is nog eenvoudiger. De klasse String heeft een speciale constructor:"

Methode Voorbeeld
String(byte bytes[])
byte[] buffer = new byte[1000];
inputStream.read(buffer);

String s = new String(buffer);
String(byte bytes[], Charset charset)
byte[] buffer = new byte[1000];
inputStream.read(buffer);

Charset koi8 = Charset.forName("KOI8-R");
String s = new String(buffer, koi8);
String(byte bytes[], String charsetName)
byte[] buffer = new byte[1000];
inputStream.read(buffer);

String s = new String(buffer, "Windows-1251");

5) Hoe converteer ik een byte-array van de ene codering naar de andere?

"Er zijn veel manieren. Hier is een van de eenvoudigste:"

Charset koi8 = Charset.forName("KOI8-R");
Charset windows1251 = Charset.forName("Windows-1251");

byte[] buffer = new byte[1000];
inputStream.read(buffer);
String s = new String(buffer, koi8);
buffer = s.getBytes(windows1251);
outputStream.write(buffer);

"Dat dacht ik al. Bedankt voor de interessante les, Rishi."