S-JIS[2022-03-23] 変更履歴
Charsetは、Javaでエンコードを扱うクラス。
|
|
キャラクターセット(java.nio.charset.Charset)は、
文字コードの種類(エンコード)を管理するクラス。[2007-02-13]
エンコードとは、例えばShift_JIS・MS932とかUTF-8とか。→エンコードの表記方法の他言語との比較
JavaのStringは内部ではUnicodeで文字列を保持しているので、例えばファイルにShift_JIS(SJIS)で出力したいときは、SJISのキャラセットをWriterに指定する。
バイト配列に特定エンコードの文字コード列を出力したいときは、String#getBytes()にキャラセットを指定する。
キャラセット名は、正式な名称の他にエイリアスが用意されている。
例えば「MS932」はエイリアスで、正式名は「windows-31j」。「SJIS」はエイリアスで、「Shift_JIS」が正式名。
Java18でデフォルトのキャラセットはUTF-8になった。[2022-03-23]
Java18より前は、デフォルトのキャラセットは実行環境依存だった。(例えばWindowsだとMS932)
現在のデフォルトのキャラセットはCharset.defaultCharset()で取得できる。
デフォルトのキャラセットを変更するには、システムプロパティーfile.encodingを指定する。
> java -Dfile.encoding=UTF-8
システムプロパティー名 | 説明 |
---|---|
file.encoding |
主にファイル入出力用(Reader・Writer)のエンコーディング。 Java18より前は環境依存の値が返る。(例えばWindowsだとMS932) Java18以降は特に指定が無い場合はUTF-8。 (Java18以降で)javaコマンドに -Dfile.encoding=COMPAT を指定すると、環境依存の値になる。(COMPATはcompatibility(互換性)のことかな?) |
native.encoding |
環境依存のエンコーディング。Java17以降。 Java17では、file.encodingと同じ値。 |
public class Encoding { public static void main(String... args) { System.out.println("file.encoding =" + System.getProperty("file.encoding")); System.out.println("native.encoding=" + System.getProperty("native.encoding")); } }
> java Encoding file.encoding =UTF-8 native.encoding=MS932 > java -Dfile.encoding=COMPAT Encoding file.encoding =MS932 native.encoding=MS932
Charsetの使用例。[2007-02-13]
import java.nio.charset.Charset; import java.nio.charset.StandardCharsets;
内容 | 例 | 備考 |
---|---|---|
デフォルトのキャラセット | Charset cs = Charset.defaultCharset(); | JDK1.5から使用可能。 システムプロパティーの「file.encoding」で指定された内容。 |
キャラセットの名前 | String name = cs.name(); | |
特定名称のキャラセット | Charset cs = Charset.forName("MS932"); | 大文字でも小文字でも取得可能。 |
特定のキャラセット | Charset cs = StandardCharsets.UTF_8; | よく使うキャラセット(JDK1.7)[2013-12-20] |
利用可能な名前 | Map m = Charset.availableCharsets(); | |
デコーダー エンコーダー | CharsetDecoder decoder = cs.newDecoder(); | →CharsetDecoderの使用例 [2009-01-16] |
import java.nio.charset.Charset;
public static void printCharsets() { // keySet()を使用した例(JDK1.4形式) // 使用可能なキャラセット SortedMap m = Charset.availableCharsets(); for (Iterator i = m.keySet().iterator(); i.hasNext();) { String name = (String) i.next(); System.out.println(name); // エイリアス Charset c = Charset.forName(name); for (Iterator j = c.aliases().iterator(); j.hasNext();) { String alias = (String) j.next(); System.out.println(" " + alias); } } }
public static void printCharsets() { // values()を使用した例(JDK1.5形式) // 使用可能なキャラセット SortedMap<String, Charset> m = Charset.availableCharsets(); for (Charset c : m.values()) { System.out.println(c.name()); // エイリアス for (String alias : c.aliases()) { System.out.println(" " + alias); } } }
Big5
csBig5
〜
EUC-JP
eucjis
x-eucjp
〜
ISO-2022-JP
jis
〜
Shift_JIS
shift-jis
x-sjis
ms_kanji
shift_jis
csShiftJIS
sjis
pck
TIS-620
US-ASCII
ISO646-US
IBM367
ASCII
cp367
default ←デフォルトはASCIIか!やっぱり(苦笑) file.encodingが「default」だと、これが使われる模様
〜
windows-31j
csWindows31J
windows-932
MS932
〜
SJIS(Shift_JIS)もMS932(Windows-31J)も どちらも似たようなキャラセットだが、いわゆる機種依存文字が対応しているかどうか(Unicodeと変換できるかどうか)が異なる。[2007-02-13]
String str = "あいうえおー−括@"; byte[] m932 = str.getBytes("MS932"); System.out.println("MS932:" + new String(m932, "MS932")); byte[] sjis = str.getBytes("SJIS"); System.out.println("SJIS :" + new String(sjis, "SJIS"));
MS932:あいうえおー−括@ SJIS :あいうえおー??? ←Shift_JISは、機種依存文字や全角ハイフンが文字化けする
なお、「?」への変換(文字化け)は、String#getBytes("SJIS")によって文字列からバイト配列へ変換(UNICODEからSJISへ変換)する際に行われる。[2009-02-14]
(コンソールへの出力の際に化けているわけではない)
for (int i = 0; i < m932.length; i++) { System.out.printf(" %02x", m932[i]); } System.out.println(); for (int i = 0; i < sjis.length; i++) { System.out.printf(" %02x", sjis[i]); } System.out.println();
82 a0 82 a2 82 a4 82 a6 82 a8 81 5b 81 7c 87 8a 87 40
82 a0 82 a2 82 a4 82 a6 82 a8 81 5b 3f 3f 3f
MS932でバイト配列に変換したもの(この時点では文字化けしていない)をSJISでString化した場合、ここでも文字化け(「?」への変換)が発生する。
System.out.println("M→S :" + new String(m932, "SJIS"));
M→S :あいうえおー???
String#getBytes()やnew String()は、内部ではCharsetDecoderやCharsetEncoderクラスが使われている。[2009-02-14]
そちらを直接使えば、変換できない文字コードを「?」にせずにエラーにする、といった処理も出来る。
→CharsetDecoderの使用例