RandomAccessFile
を使用して、テキストファイルからbyte
を読み取りました。
public static void readFile(RandomAccessFile fr) {
byte[] cbuff = new byte[1];
fr.read(cbuff,0,1);
System.out.println(new String(cbuff));
}
これで1つの完全な文字が読み取られるのはなぜですか?
char
は、Javaの文字を表します (*)。これは2バイトの大きさです(少なくとも、これは有効な値の範囲が示唆するものです)。
これは、文字のすべての表現が2バイト長であることを必ずしも意味しません。実際、多くのエンコーディングでは、すべての文字に1バイトしか予約されていません(または最も一般的な文字に1バイトを使用しています)。
String(byte[])
コンストラクターを呼び出すとき、Javaに変換してbyte[]
をプラットフォームのデフォルトエンコーディングを使用してString
に。プラットフォームのデフォルトエンコーディングは通常、ISO-8859-1などの1バイトエンコーディングまたはUTF-8などの可変長エンコーディングであるため、その1バイトを単一の文字に簡単に変換できます。
プラットフォームのデフォルトエンコーディングとしてUTF-16(またはUTF-32またはUCS-2またはUCS-4または...)を使用するプラットフォームでそのコードを実行した場合、有効な結果は得られません(代わりにUnicode置換文字を含むString
)。
これが、プラットフォームのデフォルトエンコーディングに依存しない理由の1つです。つまり、byte[]
およびchar[]
/String
またはInputStream
とReader
の間、またはOutputStream
とWriter
の間、always使用するエンコードを指定します。そうしないと、コードはプラットフォームに依存します。
(*)完全にではないtrue:char
はUTF-16コードポイントを表します。 oneまたはtwoUTF-16コードポイントは、Unicodeコードポイントを表します。 Unicodeコードポイントは通常文字を表しますが、1つの文字を構成するために複数のUnicodeコードポイントが使用される場合があります。しかし、上記の近似は、手近にあるトピックを議論するのに十分近いです。
Javaは、すべての「chars」を内部で2バイトとして保存します。ただし、文字列などになった場合、バイト数はエンコードによって異なります。
一部の文字(ASCII)はシングルバイトですが、他の多くはマルチバイトです。
JavaはUnicodeをサポートするため、次のようになります。
サポートされる最大値は、「\ uFFFF」(16進FFFF、dec 65535)、または11111111 11111111バイナリ(2バイト)です。
コンストラクターString(byte[] bytes)
は、バッファーからバイトを取得し、文字にエンコードします。
プラットフォームのデフォルト文字セットを使用して、バイトを文字にエンコードします。ファイルに異なる文字セットでエンコードされたテキストが含まれていることがわかっている場合は、String(byte[] bytes, String charsetName)
を使用して正しいエンコード(バイトから文字)を使用できます。
ASCIIテキストファイルでは、各文字は1バイトだけです
ファイルにASCII文字が含まれ、1バイトだけでエンコードされているように見えます。テキストファイルに2バイトUTF-8などの非ASCII文字が含まれている場合、最初のバイトだけが取得されます、文字全体ではありません。
ここにはいくつかの素晴らしい答えがありますが、jvmは2バイト以上の任意のサイズのスペースにchar値を自由に保存できることを指摘したかったのです。
多くのアーキテクチャでは、非境界整列メモリアクセスを実行するとペナルティが発生するため、charを簡単に4バイトにパディングできます。誤った共有を防ぐために、揮発性文字がCPUキャッシュラインのサイズに埋め込まれることさえあります。 https://en.wikipedia.org/wiki/False_sharing
New Javaプログラマにとって、文字配列または文字列が単なる複数の文字ではないことは直感的ではないかもしれません。
また、Java文字はしばしば誤用されます。16ビット長を超えるコードポイントを適切に処理しないコードを書いていることに気付かない人もいます。
JavaはUTF-16に従って文字に2バイトのうち2バイトを割り当てます。文字の保存中に最小2バイト、最大4バイトを占有します。文字用に1バイトまたは3バイトのストレージはありません。