• ベストアンサー

文字操作(エンコード)について

基礎的な質問ですがよろしくお願いします。 <内容> WINDOWS2000のデスクトップ上のファイルを別のPCのWINDOWSにコピーするプログラム を考えています。シリアルケーブルを通じて。まずファイルネームを収得してから相手PCに送信し問題なければ続いてファイルの中身を送信します。 この際、ファイルの中身がバイナリなのかテキストなのか不定のためバイナリで送受信できるように InputStream、OutputStreamを使うことに決めました。 プログラムとしてはファイル名収得後 public void sendName(String fileName){ try{ //ポートへ出力 outputstream.write(fileName.getBytes()); }catch(Exception e){ System.err.println("ファイル名書き込み失敗"); } } 上記のプログラムで送信し、受信側は StringBuffer rb = new StringBuffer(); int nData = 0; try{ while((nData = inputstream.read()) != -1){ rb.append((char)nData); } String getName = new String(rb); }catch(IOException e){ System.err.println("ファイル名読み込み失敗"); } 上記のプログラムで受信しました。 <質問> 1.結果としては日本語が文字化けしたファイル名となりましたがどこが悪いのですか? 2.ファイルの中身の送受信も同じようなプログラムで行った(受け皿はFileoutputStreamですが)ところ、ファイルの中身はちゃんと日本語の部分は日本語で表示されていました。何か違いがあるのでしょうか? 3.もしInputStreamReader、InputStreamWriterを適用した場合、ファイルの中身を収得するときに 支障は出ませんか? 4.上記のような問題について勉強できるサイトがあれば教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • mojimojio
  • ベストアンサー率51% (14/27)
回答No.2

元のプログラムのStringBufferをByteArrayOutputStreamに置き換えて、以下のような感じでしょうか。 ByteArrayOutputStream baos = new ByteArrayOutputStream(); int nData = 0; try{ while((nData = inputstream.read()) != -1){ baos.write((byte)nData); } String getName = new String(baos.toByteArray()); : 実際、InputStreamから1バイトずつ読み込むのは効率的ではありません。InputStream#read(byte[])を使った方が良いでしょう。 今回のようにStringのやり取りでしたら、writeUTF, readUTFあたりを使った方が簡単です。 <送信側> DataOutputStream dos = new DataOutputStream(outputstream); dos.writeUTF(fileName); <受信側> DataInputStream din = new DataInputStream(inputstream); String getName = din.readUTF(); こんな感じで。

cyan1110
質問者

お礼

たいへん親切な回答ありがとうございました。いろんな手法が見れて勉強になりました。

その他の回答 (2)

  • hameggs
  • ベストアンサー率38% (8/21)
回答No.3

とりあえず、Servlet/JSPでの文字化けについての 参考サイトを載せて起きますヽ(´▽`)ノ

参考URL:
http://www.ingrid.org/java/jserv/i18n/corruptedchar.html
  • mojimojio
  • ベストアンサー率51% (14/27)
回答No.1

文字化けはエンコーディングの問題ではなくて、 > while((nData = inputstream.read()) != -1){ > rb.append((char)nData); > } ここがまずいです。 byteとcharは違います。送信側はbyte列として書き込んでいるので、受信側でもbyteの配列を読み込みましょう。(1と2の違いはこの辺りだと思います) Stringとbyte列の相互変換をするとき、使用する文字エンコーディングの指定ができるようになっています。(StringのコンストラクタやgetBytes) 指定しない場合はプラットフォームのデフォルトエンコーディングが使われます。 なので、Windows同士のやり取りには問題ありませんが、他プラットフォームとの通信がありえる場合には注意が必要です。 1) 文字ストリームとして扱う必要がある場合には、 InputStreamReader, OutputStreamWriterを使う。(コンストラクタで同じエンコーディングを指定する) 2) String単位でのやり取りで良い場合には、DataOutput#writeUTF, DataInput#readUTF などを使うのが便利。StringをwriteObjectするという方法もあります。

cyan1110
質問者

お礼

回答ありがとうございます。お手数ですが受信側でbyte配列の読み込みをしてString getNameに転送するまでの書き方を教えていただけないでしょうか?

関連するQ&A