| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

「Javaでの文字コードの扱い」の版間の差分

提供: MyMemoWiki
ナビゲーションに移動 検索に移動
1行目: 1行目:
 
==Javaでの文字コードの扱い==
 
==Javaでの文字コードの扱い==
[[Java]]{{category 文字化け}}
+
[[Java]] | {{category 文字化け}}
  
 
なんだかんだといつも厄介な文字コードの変換についてのメモ
 
なんだかんだといつも厄介な文字コードの変換についてのメモ

2020年2月15日 (土) 08:36時点における版

目次

Javaでの文字コードの扱い

Java | テンプレート:Category 文字化け

なんだかんだといつも厄介な文字コードの変換についてのメモ

結局、ファイル読込み、文字列変数の取り扱い、ファイル書き込みなどの各局面で、実際はどの文字コードが使用されているかを考え、適切にコンバートすることが肝要

Javaに限らず、厄介な文字化けについて

テンプレート:Category 文字化け

基本事項

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)されている。

ソースコードの変換

ソースコードのコンパイル時、プラットフォームの文字コードやファイルの文字コードに依存してしまう。
プロパティファイルの変換
  • プロパティファイル等、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でサポートされるエンコーディング
エンコーディングの別名一覧
その他
CP943cとShift_JISの文字コードの違いについて

マルチパートのエンコード

ファイルアップロードの場合にファイル名が文字化けする

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として変換
@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

ファイルの文字コードを判別する

  • [Java ファイルの文字コードを判別する] [ファイルの文字コードを判別する]

その他

Webアプリケーションの文字化け対策

  • Filterで文字化け対策
  • 文字化けの対処

Java5.0でだいぶ機能追加があったけれど、丁寧に説明してくれてます。 試験対策でなくても非常に有用

ただ、試験範囲から外れちゃったところも多いので、こちらの本もあわせて読んでおくとよいかも(もったいないか?) テンプレート:Include html banner html, "!amazon promotion2"

その他文字化けについて

テンプレート:Category 文字化け

  • Excel VBA 文字列をバイト配列に変換
  • Filterで文字化け対策
  • HTML javascript:を利用するとデコードされる
  • J2EE Tips
  • Java ファイルの文字コードを判別する
  • Javaでの文字コードの扱い
  • Linux バックスペースが文字化けしてしまう
  • Python URLエンコード
  • Python UnicodeEncodeError の対処
  • Python ファイルの文字コード
  • SQL Plus
  • WAS から Java Mail送信で文字化け
  • vi
  • 画面に入力された文字コードを調べる
  • 文字コード
  • 文字化けの対処