「こんにちは、アミーゴ!」

「今度は、もう 1 つの興味深いトピック、エンコーディングについて説明します。」

「各文字にはコード (数字) があるということをどこかで聞いたことがあるでしょう。そのため、char 型は記号と数字の両方を表すことができます。」

「たとえば、英語のアルファベットの「A」のコードは 65 です。「B」は 66、「C」は 67 などです。大文字、小文字、キリル文字、中国語には固有のコードがあります。文字 (そう、たくさんのコード)、数字、さまざまな記号です。要するに、文字と呼ばれるもののほとんどすべてにコードが存在します。」

「では、すべての文字や文字は何らかの数字に対応しているということでしょうか?」

"正確に。"

「文字は数値に変換でき、数値は文字に変換できます。通常、Java はそれらの違いを認識しません。」

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

"面白い。"

「つまり、エンコーディングは一連のシンボルとそれに対応するコードのセットです。しかし、発明されたのは 1 つのエンコーディングだけではなく、かなりの数があります。共通のユニバーサル エンコーディングである Unicode が発明されたのは、さらに後のことです。」

「しかし、どれほど多くの普遍的な標準が発明されても、古い標準を急いで放棄する人はいません。そして、すべてがこの漫画とまったく同じように起こります。」

文字エンコーディング - 1

「ヴィンセントとニックが独自のエンコーディングを作成することにしたと想像してください。」

「これが Vincent のエンコーディングです。」
文字エンコーディング - 2

「そして、これがニックのエンコードです。」
文字エンコーディング - 3

同じ文字を使っているのに、文字コードが違うんです。

「Vincent のエンコーディングを使用して文字列 'ABC-123' がファイルに書き込まれると、次のバイト セットが得られます。」
文字エンコーディング - 4

「そして今、Nick のエンコーディングを使用する別のプログラムがファイルを読み取ろうとしています。」

「これはこうなります:«345-IJK»」

「そして最悪のことは、通常、エンコーディングはファイルのどこにも保存されないため、開発者は推測する必要があることです。」

「それで、彼らはどうやって推測するのでしょう?」

「それは別の話です。しかし、エンコーディングの扱い方について説明したいと思います。すでにご存知のとおり、Java の char のサイズは 2 バイトです。また、Java String は Unicode 形式を使用します。」

「しかし、Java では、String を、Java が認識している任意のエンコーディングのバイトのセットに変換できます。String クラスには、このための特別なメソッドがあります。Java には、特定のエンコーディングを記述する特別な Charset クラスもあります。」

1) Java がサポートするすべてのエンコーディングのリストを取得するにはどうすればよいですか?

"そのためには、availableCharsets と呼ばれる特別な静的メソッドがあります。" このメソッドは、一連のペア (エンコーディング名、エンコーディングを説明するオブジェクト) を返します。"

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

「各エンコーディングには一意の名前があります。以下にそのいくつかを示します: UTF-8、UTF-16、Windows-1251、KOI8-R など。」

2) 現在アクティブなエンコーディング (Unicode) を取得するにはどうすればよいですか?

「そのためには、defaultCharsetと呼ばれる特別なメソッドがあります。

Charset currentCharset = Charset.defaultCharset();

3) 文字列を特定のエンコーディングに変換するにはどうすればよいですか?

「Java では、Java が認識する任意のエンコーディングで String をバイト配列に変換できます。」

方法
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) ファイル内のエンコーディングがわかっている場合、ファイルから読み取ったバイト配列を String に変換するにはどうすればよいですか?

「これはさらに簡単です。String クラスには特別なコンストラクターがあります。」

方法
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) バイト配列をあるエンコーディングから別のエンコーディングに変換するにはどうすればよいですか?

「たくさんの方法があります。最も簡単な方法の 1 つを次に示します。」

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);

「そう思いました。興味深い授業をありがとう、リシ」