「Javaでの文字コードの扱い」の版間の差分
ナビゲーションに移動
検索に移動
9行目: | 9行目: | ||
*[https://www.typea.info/tips_/index.php/Java%E3%81%A7%E3%81%AE%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%89%B1%E3%81%84 Javaでの文字コードの扱い] | *[https://www.typea.info/tips_/index.php/Java%E3%81%A7%E3%81%AE%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%89%B1%E3%81%84 Javaでの文字コードの扱い] | ||
===Javaに限らず、厄介な[[文字化け]]について=== | ===Javaに限らず、厄介な[[文字化け]]について=== | ||
+ | ---- | ||
[[Category:文字化け]] | [[Category:文字化け]] | ||
14行目: | 15行目: | ||
{{amazon|481633243X}} | {{amazon|481633243X}} | ||
===基本事項=== | ===基本事項=== | ||
− | + | ---- | |
====Stringクラス==== | ====Stringクラス==== | ||
+ | ---- | ||
=====仕様では、[http://www.y-adagio.com/public/standards/tr_javalang2/typesValues.doc.html#26992 String クラス]はUnicode文字の並びを表す===== | =====仕様では、[http://www.y-adagio.com/public/standards/tr_javalang2/typesValues.doc.html#26992 String クラス]はUnicode文字の並びを表す===== | ||
− | + | ---- | |
*String クラスのソースコード(%JAVA_HOME%/src.zip)を見ると、Unicode文字の並びをchar型の配列として保持している。 | *String クラスのソースコード(%JAVA_HOME%/src.zip)を見ると、Unicode文字の並びをchar型の配列として保持している。 | ||
*[http://e-words.jp/w/Unicode.html char型|http://www.y-adagio.com/public/standards/tr_javalang2/typesValues.doc.html#48440]は、[Unicode]文字を表す16ビット符号無し整数で、'\u0000'~'\uffff' すなわち 0~65535を表現できる | *[http://e-words.jp/w/Unicode.html char型|http://www.y-adagio.com/public/standards/tr_javalang2/typesValues.doc.html#48440]は、[Unicode]文字を表す16ビット符号無し整数で、'\u0000'~'\uffff' すなわち 0~65535を表現できる | ||
24行目: | 26行目: | ||
====ソースコードの変換==== | ====ソースコードの変換==== | ||
+ | ---- | ||
=====ソースコードのコンパイル時、プラットフォームの[[文字コード]]やファイルの[[文字コード]]に依存してしまう。===== | =====ソースコードのコンパイル時、プラットフォームの[[文字コード]]やファイルの[[文字コード]]に依存してしまう。===== | ||
− | + | ---- | |
*[[Windows]]でソースを書いてLinuxでコンパイルを行ったりするような場合には、プラットフォームとソースコードの文字コードの不一致によって文字化けが発生する。 | *[[Windows]]でソースを書いてLinuxでコンパイルを行ったりするような場合には、プラットフォームとソースコードの文字コードの不一致によって文字化けが発生する。 | ||
*[http://www.y-adagio.com/public/standards/tr_javalang2/lexical.doc.html#100850 native2ascii|http://java.sun.com/j2se/1.5.0/ja/docs/ja/tooldocs/windows/native2ascii.html] を使用して、ソースコードに含まれるUnicode以外の文字を、[Unicodeエスケープ]に変換する。 | *[http://www.y-adagio.com/public/standards/tr_javalang2/lexical.doc.html#100850 native2ascii|http://java.sun.com/j2se/1.5.0/ja/docs/ja/tooldocs/windows/native2ascii.html] を使用して、ソースコードに含まれるUnicode以外の文字を、[Unicodeエスケープ]に変換する。 | ||
=====プロパティファイルの変換===== | =====プロパティファイルの変換===== | ||
+ | ---- | ||
*プロパティファイル等、Java プログラムで利用するファイルも、ソースコード同様、[http://java.sun.com/j2se/1.5.0/ja/docs/ja/tooldocs/windows/native2ascii.html native2ascii] を使用して文字コードを変換する。 | *プロパティファイル等、Java プログラムで利用するファイルも、ソースコード同様、[http://java.sun.com/j2se/1.5.0/ja/docs/ja/tooldocs/windows/native2ascii.html native2ascii] を使用して文字コードを変換する。 | ||
35行目: | 39行目: | ||
プログラムの実行時にファイルを読込む必要がある場合等は、ファイルに合わせた[[文字コード]]でファイルを読まなければ文字化けしてしまう場合がある。 | プログラムの実行時にファイルを読込む必要がある場合等は、ファイルに合わせた[[文字コード]]でファイルを読まなければ文字化けしてしまう場合がある。 | ||
====[[文字コード]]を指定してファイルを読む==== | ====[[文字コード]]を指定してファイルを読む==== | ||
+ | ---- | ||
=====FileInputStream を利用することにより、[[文字コード]]を指定してファイルを読むことができる===== | =====FileInputStream を利用することにより、[[文字コード]]を指定してファイルを読むことができる===== | ||
+ | ---- | ||
Buffered[[R]]eader reader | Buffered[[R]]eader reader | ||
= new Buffered[[R]]eader(new InputStream[[R]]eader(new FileInputStream("/var/files/ebicdic.txt"),"Cp943c")); | = new Buffered[[R]]eader(new InputStream[[R]]eader(new FileInputStream("/var/files/ebicdic.txt"),"Cp943c")); | ||
====[[文字コード]]を指定してファイルを書く==== | ====[[文字コード]]を指定してファイルを書く==== | ||
+ | ---- | ||
=====FileInputStream を利用することにより、[[文字コード]]を指定してファイルを書くことができる===== | =====FileInputStream を利用することにより、[[文字コード]]を指定してファイルを書くことができる===== | ||
+ | ---- | ||
BufferedWriter writer | BufferedWriter writer | ||
= new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:\\shift_jis.txt"), "MS932")) | = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:\\shift_jis.txt"), "MS932")) | ||
===[[文字コード]]の変換=== | ===[[文字コード]]の変換=== | ||
+ | ---- | ||
<blockquote>nicodeで定義された文字集合で表現された文字列" から "バイト列" へのエンコード方法、逆にデコード方法を指定する。</blockquote> | <blockquote>nicodeで定義された文字集合で表現された文字列" から "バイト列" へのエンコード方法、逆にデコード方法を指定する。</blockquote> | ||
====エンコード==== | ====エンコード==== | ||
+ | ---- | ||
=====エンコード方式(文字セット)を指定して、Stringからバイト列を取得する===== | =====エンコード方式(文字セット)を指定して、Stringからバイト列を取得する===== | ||
+ | ---- | ||
byte[] String.getBytes(String charsetName) | byte[] String.getBytes(String charsetName) | ||
+ | |||
*java.lang.StringCoding.encode(String charsetName, char[] value ...) | *java.lang.StringCoding.encode(String charsetName, char[] value ...) | ||
*sun.io.CharToByteConverter | *sun.io.CharToByteConverter | ||
====デコード==== | ====デコード==== | ||
+ | ---- | ||
=====デコード方式(文字セット)を指定して、バイト列からStringを生成する===== | =====デコード方式(文字セット)を指定して、バイト列からStringを生成する===== | ||
+ | ---- | ||
new String(byte[] bytes, String charsetName) | new String(byte[] bytes, String charsetName) | ||
*java.lang.StringCoding.decode(String charsetName, byte[] bytes ...) | *java.lang.StringCoding.decode(String charsetName, byte[] bytes ...) | ||
59行目: | 73行目: | ||
====[[文字コード]]の変換==== | ====[[文字コード]]の変換==== | ||
+ | ---- | ||
=====上記を使用して、[[文字コード]]を変換する===== | =====上記を使用して、[[文字コード]]を変換する===== | ||
+ | ---- | ||
String newCode = new String(oldCode.getBytes("Cp930"), "MS932"); | String newCode = new String(oldCode.getBytes("Cp930"), "MS932"); | ||
====デフォルトエンコード(デコード)==== | ====デフォルトエンコード(デコード)==== | ||
+ | ---- | ||
=====エンコード(デコード)方式を指定しないと、プラットフォームのデフォルト[[エンコーディング]]が使用される。===== | =====エンコード(デコード)方式を指定しないと、プラットフォームのデフォルト[[エンコーディング]]が使用される。===== | ||
+ | ---- | ||
システムプロパティ | システムプロパティ | ||
88行目: | 106行目: | ||
====[[文字コード]]の16進ダンプ==== | ====[[文字コード]]の16進ダンプ==== | ||
+ | ---- | ||
=====デバッグ用===== | =====デバッグ用===== | ||
+ | ---- | ||
public static String stringDump(String s) { | public static String stringDump(String s) { | ||
if (s == null) return ""; | if (s == null) return ""; | ||
99行目: | 119行目: | ||
} | } | ||
====[[文字コード]]の16進ダンプを復元==== | ====[[文字コード]]の16進ダンプを復元==== | ||
+ | ---- | ||
=====デバッグ用===== | =====デバッグ用===== | ||
+ | ---- | ||
public static String decodeDumpString(String s) { | public static String decodeDumpString(String s) { | ||
StringBuffer result = new StringBuffer(); | StringBuffer result = new StringBuffer(); | ||
116行目: | 138行目: | ||
====[[エンコーディング]]==== | ====[[エンコーディング]]==== | ||
+ | ---- | ||
*[[文字コード]] | *[[文字コード]] | ||
*[http://ja.wikipedia.org/wiki/Microsoft%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9A%E3%83%BC%E3%82%B8932 Microsoftコードページ932] | *[http://ja.wikipedia.org/wiki/Microsoft%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9A%E3%83%BC%E3%82%B8932 Microsoftコードページ932] | ||
121行目: | 144行目: | ||
=====Javaでサポートされる[[エンコーディング]]===== | =====Javaでサポートされる[[エンコーディング]]===== | ||
+ | ---- | ||
*[http://java.sun.com/j2se/1.3/ja/docs/ja/guide/intl/encoding.doc.html 1.3|http://java.sun.com/j2se/1.3/docs/guide/intl/encoding.doc.html]([日本語]) | *[http://java.sun.com/j2se/1.3/ja/docs/ja/guide/intl/encoding.doc.html 1.3|http://java.sun.com/j2se/1.3/docs/guide/intl/encoding.doc.html]([日本語]) | ||
*[http://java.sun.com/j2se/1.4/ja/docs/ja/guide/intl/encoding.doc.html 1.4|http://java.sun.com/j2se/1.4/docs/guide/intl/encoding.doc.html]([日本語]) | *[http://java.sun.com/j2se/1.4/ja/docs/ja/guide/intl/encoding.doc.html 1.4|http://java.sun.com/j2se/1.4/docs/guide/intl/encoding.doc.html]([日本語]) | ||
126行目: | 150行目: | ||
=====[[エンコーディング]]の別名一覧===== | =====[[エンコーディング]]の別名一覧===== | ||
+ | ---- | ||
*[http://www2s.biglobe.ne.jp/~katsum/java/encoding.html sun.io.CharacterEncoding] | *[http://www2s.biglobe.ne.jp/~katsum/java/encoding.html sun.io.CharacterEncoding] | ||
=====[[その他]]===== | =====[[その他]]===== | ||
+ | ---- | ||
*MS932またはSJISの別名として定義されており、どちらの別名となるかはバージョンに依存している(JDK 1.3ではMS932だが、JDK 1.4ではSJISとなる)。 | *MS932またはSJISの別名として定義されており、どちらの別名となるかはバージョンに依存している(JDK 1.3ではMS932だが、JDK 1.4ではSJISとなる)。 | ||
*http://www.atmarkit.co.jp/fjava/rensai2/webopt08/webopt08.html | *http://www.atmarkit.co.jp/fjava/rensai2/webopt08/webopt08.html | ||
=====CP943cとShift_JISの[[文字コード]]の違いについて===== | =====CP943cとShift_JISの[[文字コード]]の違いについて===== | ||
+ | ---- | ||
*http://www-1.ibm.com/support/doc[[vi]]ew.wss?uid=std3b32aea767378855449256f010028e2f4 | *http://www-1.ibm.com/support/doc[[vi]]ew.wss?uid=std3b32aea767378855449256f010028e2f4 | ||
===マルチパートのエンコード=== | ===マルチパートのエンコード=== | ||
+ | ---- | ||
====ファイルアップロードの場合にファイル名が[[文字化け]]する==== | ====ファイルアップロードの場合にファイル名が[[文字化け]]する==== | ||
+ | ---- | ||
=====Form===== | =====Form===== | ||
+ | ---- | ||
<form id="formUpload" action="upload.html" method="POST" enctype="multipart/form-data" > | <form id="formUpload" action="upload.html" method="POST" enctype="multipart/form-data" > | ||
<input name="attach_file" /> | <input name="attach_file" /> | ||
144行目: | 174行目: | ||
=====[[文字コード]]をiso-8859-1として変換===== | =====[[文字コード]]をiso-8859-1として変換===== | ||
+ | ---- | ||
*http://ja.wikipedia.org/wiki/ISO/[[IE]]C_8859-1 | *http://ja.wikipedia.org/wiki/ISO/[[IE]]C_8859-1 | ||
*[[Spring]] の場合 | *[[Spring]] の場合 | ||
153行目: | 184行目: | ||
====ファイルダウンロード時にファイル名が[[文字化け]]する==== | ====ファイルダウンロード時にファイル名が[[文字化け]]する==== | ||
+ | ---- | ||
//String fileName = new String(originalFileName.getBytes("utf-8"),"iso-8859-1"); // Chrome OK, [[IE]] NG | //String fileName = new String(originalFileName.getBytes("utf-8"),"iso-8859-1"); // Chrome OK, [[IE]] NG | ||
String fileName = new String(originalFileName.getBytes("ms932"),"iso-8859-1"); // Chrome OK, [[IE]] OK | String fileName = new String(originalFileName.getBytes("ms932"),"iso-8859-1"); // Chrome OK, [[IE]] OK | ||
160行目: | 192行目: | ||
===Shift_JISの取り扱い=== | ===Shift_JISの取り扱い=== | ||
+ | ---- | ||
*MS932またはSJISの別名として定義されており、どちらの別名となるかはバージョンに依存している(JDK 1.3ではMS932だが、JDK 1.4ではSJISとなる)。 | *MS932またはSJISの別名として定義されており、どちらの別名となるかはバージョンに依存している(JDK 1.3ではMS932だが、JDK 1.4ではSJISとなる)。 | ||
169行目: | 202行目: | ||
=====円記号===== | =====円記号===== | ||
+ | ---- | ||
*Shift_JISでは、半角円記号とバックスラッシュを区別しないが、する[[文字コード]]体系だと見た目上は、半角円記号なのに、Stringのメソッドが正しく動作しない(ように見える) | *Shift_JISでは、半角円記号とバックスラッシュを区別しないが、する[[文字コード]]体系だと見た目上は、半角円記号なのに、Stringのメソッドが正しく動作しない(ように見える) | ||
String str1 = "\u005c\u005c"; | String str1 = "\u005c\u005c"; | ||
178行目: | 212行目: | ||
false | false | ||
===ファイルの[[文字コード]]を判別する=== | ===ファイルの[[文字コード]]を判別する=== | ||
+ | ---- | ||
*[[Java ファイルの文字コードを判別する|ファイルの文字コードを判別する]] | *[[Java ファイルの文字コードを判別する|ファイルの文字コードを判別する]] | ||
===[[その他]]=== | ===[[その他]]=== | ||
+ | ---- | ||
{{amazon|4774107808}} | {{amazon|4774107808}} | ||
====[[Webアプリケーション]]の文字化け対策==== | ====[[Webアプリケーション]]の文字化け対策==== | ||
+ | ---- | ||
*[[Filterで文字化け対策]] | *[[Filterで文字化け対策]] | ||
*[[文字化けの対処]] | *[[文字化けの対処]] | ||
− | + | ||
{{amazon|4822282775}} | {{amazon|4822282775}} | ||
[[Java5]].0でだいぶ機能追加があったけれど、丁寧に説明してくれてます。 | [[Java5]].0でだいぶ機能追加があったけれど、丁寧に説明してくれてます。 | ||
194行目: | 231行目: | ||
===その他[[文字化け]]について=== | ===その他[[文字化け]]について=== | ||
+ | ---- | ||
[[Category:文字化け]] | [[Category:文字化け]] | ||
*[[Excel VBA 文字列をバイト配列に変換]] | *[[Excel VBA 文字列をバイト配列に変換]] |
2021年8月10日 (火) 05:26時点における版
目次
Javaでの文字コードの扱い
Java |
なんだかんだといつも厄介な文字コードの変換についてのメモ
結局、ファイル読込み、文字列変数の取り扱い、ファイル書き込みなどの各局面で、実際はどの文字コードが使用されているかを考え、適切にコンバートすることが肝要
Javaに限らず、厄介な文字化けについて
基本事項
Stringクラス
仕様では、String クラスはUnicode文字の並びを表す
- String クラスのソースコード(%JAVA_HOME%/src.zip)を見ると、Unicode文字の並びをchar型の配列として保持している。
- char型|http://www.y-adagio.com/public/standards/tr_javalang2/typesValues.doc.html#48440は、[Unicode]文字を表す16ビット符号無し整数で、'\u0000'~'\uffff' すなわち 0~65535を表現できる
- Javaで扱うUnicodeは、1文字を16ビット(2バイト)UCS-2である。
- 現在はUnicode全体は4バイトで定義(UCS-4)されている。
ソースコードの変換
ソースコードのコンパイル時、プラットフォームの文字コードやファイルの文字コードに依存してしまう。
- Windowsでソースを書いてLinuxでコンパイルを行ったりするような場合には、プラットフォームとソースコードの文字コードの不一致によって文字化けが発生する。
- native2ascii|http://java.sun.com/j2se/1.5.0/ja/docs/ja/tooldocs/windows/native2ascii.html を使用して、ソースコードに含まれるUnicode以外の文字を、[Unicodeエスケープ]に変換する。
プロパティファイルの変換
- プロパティファイル等、Java プログラムで利用するファイルも、ソースコード同様、native2ascii を使用して文字コードを変換する。
ファイルの読み書き
プログラムの実行時にファイルを読込む必要がある場合等は、ファイルに合わせた文字コードでファイルを読まなければ文字化けしてしまう場合がある。
文字コードを指定してファイルを読む
FileInputStream を利用することにより、文字コードを指定してファイルを読むことができる
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("/var/files/ebicdic.txt"),"Cp943c"));
文字コードを指定してファイルを書く
FileInputStream を利用することにより、文字コードを指定してファイルを書くことができる
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:\\shift_jis.txt"), "MS932"))
文字コードの変換
<blockquote>nicodeで定義された文字集合で表現された文字列" から "バイト列" へのエンコード方法、逆にデコード方法を指定する。</blockquote>
エンコード
エンコード方式(文字セット)を指定して、Stringからバイト列を取得する
byte[] String.getBytes(String charsetName)
- java.lang.StringCoding.encode(String charsetName, char[] value ...)
- sun.io.CharToByteConverter
デコード
デコード方式(文字セット)を指定して、バイト列からStringを生成する
---- new String(byte[] bytes, String charsetName)
- java.lang.StringCoding.decode(String charsetName, byte[] bytes ...)
- sun.io.ByteToCharConverter
文字コードの変換
----
上記を使用して、文字コードを変換する
---- String newCode = new String(oldCode.getBytes("Cp930"), "MS932");
デフォルトエンコード(デコード)
----
エンコード(デコード)方式を指定しないと、プラットフォームのデフォルトエンコーディングが使用される。
----
システムプロパティ
名前 | 説明 | 例 |
---|---|---|
file.encoding | デフォルトのコード系 | MS932 |
file.encoding.pkg | コード系を取り扱うパッケージ | sun.io |
line.separator | 行のセパレータ | CRLF |
- System.getProperty("file.encoding")
- sun.io.Converters.getDefaultEncodingName()
文字コードの16進ダンプ
----
デバッグ用
---- public static String stringDump(String s) { if (s == null) return ""; StringBuffer buf = new StringBuffer(); char[] c = s.toCharArray(); for (int i=0; i<c.length; i++) { buf.append(Integer.toString((int)c[i], 16) + " "); } return buf.toString(); }
文字コードの16進ダンプを復元
----
デバッグ用
---- public static String decodeDumpString(String s) { StringBuffer result = new StringBuffer(); StringTokenizer tok = new StringTokenizer(s.trim(), " "); List lst = new ArrayList(); while(tok.hasMoreTokens()) { lst.add(new Character((char)Integer.parseInt(tok.nextToken(),16))); } char[] buf = new char[lst.size()]; for (int i=0; i<lst.size(); i++) { buf[i] = ((Character)lst.get(i)).charValue(); } return (new String(buf)); }
エンコーディング
----
Javaでサポートされるエンコーディング
----
- 1.3|http://java.sun.com/j2se/1.3/docs/guide/intl/encoding.doc.html([日本語])
- 1.4|http://java.sun.com/j2se/1.4/docs/guide/intl/encoding.doc.html([日本語])
- 1.5|http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html([日本語])
エンコーディングの別名一覧
----
その他
----
- MS932またはSJISの別名として定義されており、どちらの別名となるかはバージョンに依存している(JDK 1.3ではMS932だが、JDK 1.4ではSJISとなる)。
- http://www.atmarkit.co.jp/fjava/rensai2/webopt08/webopt08.html
CP943cとShift_JISの文字コードの違いについて
----
- http://www-1.ibm.com/support/docview.wss?uid=std3b32aea767378855449256f010028e2f4
マルチパートのエンコード
----
ファイルアップロードの場合にファイル名が文字化けする
----
Form
---- <form id="formUpload" action="upload.html" method="POST" enctype="multipart/form-data" > <input name="attach_file" /> <input type="submit" value="アップロード"/> </form>
文字コードをiso-8859-1として変換
----
- http://ja.wikipedia.org/wiki/ISO/IEC_8859-1
- Spring の場合
@RequestMapping(value="/upload.html", method = RequestMethod.POST) public String uploadFile(MultipartFile file) { String filename = new String(file.getOriginalFilename().getBytes("iso-8859-1"),"utf-8"); :
ファイルダウンロード時にファイル名が文字化けする
---- //String fileName = new String(originalFileName.getBytes("utf-8"),"iso-8859-1"); // Chrome OK, IE NG String fileName = new String(originalFileName.getBytes("ms932"),"iso-8859-1"); // Chrome OK, IE OK response.setHeader("Content-Type", "application/octet-stream"); response.setHeader("Content-Disposition", "filename=\"" + fileName + "\"");
Shift_JISの取り扱い
----
- MS932またはSJISの別名として定義されており、どちらの別名となるかはバージョンに依存している(JDK 1.3ではMS932だが、JDK 1.4ではSJISとなる)。
- 機種依存文字(NEC特殊文字、NEC選定IBM拡張文字、IBM拡張文字)や~∥-¢£¬などの扱いが異なり、誤って使用すると“?”に文字化け
- 文字コード 参照
円記号
----
- Shift_JISでは、半角円記号とバックスラッシュを区別しないが、する文字コード体系だと見た目上は、半角円記号なのに、Stringのメソッドが正しく動作しない(ように見える)
String str1 = "\u005c\u005c"; String str2 = "\u00a5"; System.out.println(str1 + " = " + str2); System.out.println(str1.equals(str2));
\ = \ false
ファイルの文字コードを判別する
----
その他
----
Webアプリケーションの文字化け対策
----
Java5.0でだいぶ機能追加があったけれど、丁寧に説明してくれてます。 試験対策でなくても非常に有用
ただ、試験範囲から外れちゃったところも多いので、こちらの本もあわせて読んでおくとよいかも(もったいないか?) {{include_html banner_html, "!amazon_promotion2"}}
その他文字化けについて
----
© 2006 矢木浩人