- PR -

文字コード確認方法

投稿者投稿内容
begood
ベテラン
会議室デビュー日: 2003/09/12
投稿数: 97
お住まい・勤務地: とうきょー
投稿日時: 2003-10-20 18:00
FileWriter等で、ファイルを保存しましたが、そのときに、文字コードをeuc-jp型で保存するように指示があり、Stringクラスのコンストラクタでeucに変更して、ファイルに保存しました。(実際にはcsvフォーマット)そのときに、このファイルが本当にeuc-jpのキャラクター型になっているかどうかを確認したいのですが、どのような方法があるか、アドバイスもらえませんか?csvをwindowsで開くとやはり、?????マークが出てきます。(もちろんSJIS等で保存する形をとれば、正常な文字はでます。)
とまと
ベテラン
会議室デビュー日: 2003/10/18
投稿数: 51
投稿日時: 2003-10-20 18:16
こんにちは。

引用:

begoodさんの書き込み (2003-10-20 18:00) より:
このファイルが本当にeuc-jpのキャラクター型になっているかどうかを確認したいのですが、どのような方法があるか、アドバイスもらえませんか?



いくつか方法があると思います。
・視覚的に調べる
(1)EUCに対応したエディタ(私はviviを使っています)で見てみる。
(2)nkfなどのキャラクタコンバータを使用してWindows-31J(あるいはSJIS)に変換し、
 メモ帳などで見てみる。

・コード表で調べる
ファイルをバイトストリームで読み込み、
文字コードがEUCのマッピングに
従っているか確認する。

などでしょうか。
eiji
常連さん
会議室デビュー日: 2003/07/23
投稿数: 32
投稿日時: 2003-10-20 18:20

FileWriterクラスには、unicodeから、ディフォルトエンコーディングに
自動的に変換するクラスなので、
OSのディフォルトエンコーディングが、
euc-jpなら、わざわざ、eucに変換してから
使用する必要は無いような気がします。
2重で変換が発生しているのではないでしょうか?
うのきち
ベテラン
会議室デビュー日: 2003/02/17
投稿数: 55
投稿日時: 2003-10-20 18:34
引用:

begoodさんの書き込み (2003-10-20 18:00) より:
FileWriter等で、ファイルを保存しましたが、そのときに、文字コードをeuc-jp型で保存するように指示があり、Stringクラスのコンストラクタでeucに変更して、ファイルに保存しました。(実際にはcsvフォーマット)そのときに、このファイルが本当にeuc-jpのキャラクター型になっているかどうかを確認したいのですが、どのような方法があるか、アドバイスもらえませんか?csvをwindowsで開くとやはり、?????マークが出てきます。(もちろんSJIS等で保存する形をとれば、正常な文字はでます。)



?????になっているなら、正しく動作していません。

やりたいことは、Windowsマシンで、EUCで保存したいという事でよろしいですか?
だとすると、FileWriterではなくて、OutputStreamWriterとFileOutputStreamを組み合わせるのが良いと思います。OutputStreamWriterは、コンストラクタでキャラクタセットを明示的に指定できますから、ここにEUCを指定すれば良いでしょう。Stringクラスを使ったエンコーディング変換は必要ありません。
とまと
ベテラン
会議室デビュー日: 2003/10/18
投稿数: 51
投稿日時: 2003-10-20 18:35
こんにちは。

eijiさんがご指摘している点にも関連すると思いますが、
何故Stringコンストラクタに文字コード(EUC)を指定する必要が
あったのか、begoodさんの情報だけでは
わかりませんね。
もし、Stringコンストラクタに渡したbyte配列が、
EUCコードの文字バイト列ならば問題はありませんが。。。

String(Unicode)をファイルにEUCで出力したいのなら、
OutputStreamWriterインスタンス生成時に文字コードを
指定するなどする必要があると思います。
eijiさんのおっしゃる通り、
デフォルトエンコーディングがEUCなら、その必要は
ありませんね。
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2003-10-20 18:47
引用:

begoodさんの書き込み (2003-10-20 18:00) より:
FileWriter等で、ファイルを保存しましたが、そのときに、文字コードをeuc-jp型で保存するように指示があり、Stringクラスのコンストラクタでeucに変更して、ファイルに保存しました。


文字コードを指定して保存するときは、FileInputStreamとOutputStreamWriterを使ってください。
また、StringのコンストラクタとはString(byte[] bytes, String charsetName)を指しているものと思いますが、このコンストラクタは指定した文字コードのバイト配列から、UnicodeのStringインスタンスを構築するためのものです。
String#getBytes(String charsetName)がその逆にあたりますが、OutputStreamWriterを使う分には必要ありません。

引用:

(実際にはcsvフォーマット)そのときに、このファイルが本当にeuc-jpのキャラクター型になっているかどうかを確認したいのですが、どのような方法があるか、アドバイスもらえませんか?csvをwindowsで開くとやはり、?????マークが出てきます。(もちろんSJIS等で保存する形をとれば、正常な文字はでます。)


????が表示されるとしたら、おそらく保存は失敗していると思います。eucで保存したファイルをShift-JISで開くと、大抵の場合、半角カナが大量に表示されます。
(?はjavaで文字コード変換が失敗したときに割り当てられる文字です。)

検証する方法は、とまと氏のおっしゃるようにEUC対応エディタで開いてみるのが手っ取り早いと思います。フリーのテキストエディタでもいくつもあります。
また、JavaでInputStreamReaderを使い、EUCを指定して開いてみるコードを作ってもよいでしょう。
begood
ベテラン
会議室デビュー日: 2003/09/12
投稿数: 97
お住まい・勤務地: とうきょー
投稿日時: 2003-10-21 02:27
皆様、アドバイスありがとうございました。無事にできました。しかしながら・・・
使用機種はWindowsのDOS/Vです。デフォルトはSJISになっています。指定で、保存はEUCにするという仕様なのでそのようにしています。実際にはWindowsマシンでは仕様されないのでしょう・・・。また、Stringのコンストラクタにeuc_jpしたのは、文字コードの変換に関してはあまり存じ上げていなかったためです。(半導体関連出身で、あまり、文字コード変換についてしらず・・・)でも、少しずつわかり始めてきているのですが・・・。

それから、????が出るのはやはり正常ではなかったのですね。(あまりにも素人すぎで・・・すいません。)デフォルトがSJISになっていたので、(Webから受け取る文字)一度SJISでString型のインスタンスを作成してから、ファイルに入れるときにeuc_jpにて保存しないといけなかったのですね・・・。ここの部分で、SJISのインスタンスをつくらないといけないのか、そのままなのか、どうなのかがちょっと引っかかっており、テストをしようとしても????ばかり出てしまい、うまくテストできずに困っておりました。

でも、実際に、getBytesを使用しないとうまくいかないですね・・・。euc-jpの文字フォーマットにするときにString型の文字はどのようなフォーマットであればよいのでしょう???。確かに、Stringの変数にコード上でじかに文字をいれれば、getBytesは必要ないですが、SJISでWeb上でもらってくるときはgetBytesは必要ですか?(これを入れないと正常にEUCで表示されなかったもので・・・)

いまいち、文字コードがわかっていないもので、すいません・・・

とまと
ベテラン
会議室デビュー日: 2003/10/18
投稿数: 51
投稿日時: 2003-10-21 07:09
おはようございます。

既に解決されたと思いますが、
Windows-31JコードのデータをEUCコードでファイルに出力する
code fragmentです。

コード:
// Windows-31Jコードで"とまと"
byte[] buffer = new byte[]{
		(byte)0x82, (byte)0xc6,	
		(byte)0x82, (byte)0xdc,
		(byte)0x82, (byte)0xc6};

// Windows-31JコードをJava Stringの内部コードである
// Unicodeに変換する		
String theString = new String(buffer, "Windows-31J");
System.out.println(theString);
		
// String(Unicode)をEUCコードでファイルに出力する
FileOutputStream fos = new FileOutputStream("tmp.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "EUC_JP");
PrintWriter pw = new PrintWriter(osw);
pw.print(theString);



引用:

この部分で、SJISのインスタンスをつくらないといけないのか、そのままなのか、どうなのかがちょっと引っかかっており、
<snip>
でも、実際に、getBytesを使用しないとうまくいかないですね・・・。euc-jpの文字フォーマットにするときにString型の文字はどのようなフォーマットであればよいのでしょう???。確かに、Stringの変数にコード上でじかに文字をいれれば、getBytesは必要ないですが、SJISでWeb上でもらってくるときはgetBytesは必要ですか?(これを入れないと正常にEUCで表示されなかったもので・・・)


環境、プログラムなどに関する情報が少ないため、
前提が間違っているかもしれませんが、
HTMLフォームでユーザが入力したテキストデータ(Windows-31Jで送信される)を
サーブレットが受信するケースと仮定します。
この場合、環境(アプリケーションサーバの種類やその設定など)によっては
次のように取得したfirstName文字列には期待した通りの値が入っていない
ことがあります。

コード:
// requestはHttpServletRequestオブジェクト
String firstName = reqeust.getParameter("firstName");



これは、Webシステムを開発したことがある人ならば非常に有名な問題です。
サーブレットコンテナでは、クライアントから送られてきたデータがどの文字コードで
エンコーディングされているか判断できず、
クライアントからのデータがISO-8859-1コードであるとして、
Java Stringの内部コードであるUnicodeに変換しているため発生します。
従って、サーブレットでこのデータを正しく取得するために、
以下のようなコードを記述したりします。
コード:
// ISO-8859-1 ---> Unicode変換されている
String firstName = request.getParameter("firstName");

// Unicode ---> ISO-8859-1変換してやる(逆変換)
// これによって、Windows-31Jで送られたデータを復元できる
byte[] buffer = firstName.getBytes("ISO-8859-1");

// Windows-31J ---> Unicode変換してやる
firstName = new String(buffer, "Windows-31J");

// ユーザが入力した文字列が正しく表示される。
System.out.println(firstName);



ただ、私はこのようなコードを久しく書いておらず、
次のような対応を取るケースが多いです。
・アプリケーションサーバにデフォルトエンコーディングを設定して(この場合Windows-31J)、
 自動的にコード変換するようにする。
 ほとんどのアプリケーションサーバがこのような機能を提供している。
 ただし、設定方法はアプリケーションサーバに固有である。
・ServletAPI2.3に対応しているアプリケーションサーバならば、
 フィルタで HttpServletRequest.setCharacterEncoding("Windows-31J") を
 利用してエンコーディングを設定する。
 これによって、サーブレットでは reqeust.getParameter("aaa") としても、
 文字化けは発生しない。

特に、Strutsフレームワークを利用するような場合は
このような対応が簡単な解決方法になるでしょう。
また、文字化けに関する様々な問題は、
いろいろなサイトで紹介されています。
検索エンジンをご利用されるとよいと思います。

最後にJava Stringの内部を表現する文字コードは、
文字化けするしないに関わらず
「常に」Unicodeであるということをご指摘したいと思います。

スキルアップ/キャリアアップ(JOB@IT)