• 締切済み

UTF-16LEにエンコード

テキストファイル(ASCII)をUTF-16LEに文字コード変換するプログラムを作成したいのですが、 期待通りの結果がえられません。 下記のプログラムに問題があればご教授下さい。 (文字数の関係でコメント文を省略しました。) -------------------- StringsInputFile=args[0]; StringsOutputFile=args[1]; CharsetutfCharset=Charset.forName("UTF-16LE"); CharsetEncoderencoder=utfCharset.newEncoder(); ByteBufferutfBytes=null; try{ FileInputStreaminput=newFileInputStream(sInput); FileOutputStreamoutput=newFileOutputStream(sOutput); bytebuf[]=newbyte[256]; intlen; while((len=input.read(buf))!=-1){ ByteBufferunicodeBytes=ByteBuffer.wrap(buf); try{ utfBytes=encoder.encode(unicodeBytes.asCharBuffer()); } catch(CharacterCodingExceptione){ System.out.println("EncodeError!!["+e.getMessage()+"]"); continue; } output.write(utfBytes.array(),0,len); } output.flush(); output.close(); input.close(); }catch(FileNotFoundExceptione){ }catch(IOExceptione){ } return; } -------------------- 入力ファイルの中身は[TEST]と入力されています。 上記プログラムで得られた結果(出力ファイル) をバイナリエディタで確認すると 期待結果は [5400450053005400] なのですが、 [45545453](テキスト表示すると[ETTS]) となってしまいます。 できれば、BOM(FFFE)も先頭に付加したいです。 以上、宜しくお願い致します。

  • Java
  • 回答数3
  • ありがとう数5

みんなの回答

  • UKY
  • ベストアンサー率50% (604/1207)
回答No.3

> unicodeBytes.asCharBuffer() ByteBuffer を CharBuffer に変換したいんでしょうが、これではうまくいきません。 これは 2n バイトの ByteBuffer を 2 バイトずつ区切って n 文字の CharBuffer に変換せよという意味になります。 そもそも元のファイルから読み取ったデータをそのままむりやり文字に変換しようとしているのが誤りです。 元のファイルは ASCII でエンコーディングされているのですから、まずデータを ASCII バイト列から文字列に変換 (デコード) した上でそれを UTF-16 バイト列に変換 (エンコード) しなくてはなりません。 デコードの仕方はエンコードの仕方と似ているので調べればすぐ分かるでしょう。

CSCASE
質問者

お礼

回答ありがとうございます。 大変参考になりました。

  • T0ngT0ng
  • ベストアンサー率40% (8/20)
回答No.2

#1です 補足しときますと、元々のソースのほうは変換元がASCII であるために失敗しているんだと思います。 CharsetEncoderのAPIには "16 ビット Unicode 文字のシーケンスを特定の文字 セットで表現されたバイトシーケンスに変換する エンジンです。" とありますので、ASCII文字列をUnicode(Big Endian) だと思って変換しちゃうんでしょうね。

CSCASE
質問者

お礼

お礼が遅くなり申し訳ありません。 大変参考になりました。 ありがとうございました。

  • T0ngT0ng
  • ベストアンサー率40% (8/20)
回答No.1

OutputStreamWriterでエンコード指定しちゃうのが楽そうです。 (いずれにしても BOMは直接書かないとだめそうですが) 簡単には以下のようになりますか・・・ FileOutputStream fos = new FileOutputStream("./test.txt"); byte[] BOM={(byte)0xFF,(byte)0xFE}; fos.write(BOM); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-16LE"); osw.write("TEST"); osw.close();

CSCASE
質問者

お礼

お礼が遅くなり申し訳ありません。 まさにピンポイントのご回答でした。 ありがとうございました。

関連するQ&A

  • ファイルロック後の書き込みについて

    ファイルAをロックしファイルBを読み込み ファイルAに書き込むプログラムを作成しています。 単体起動では問題無く動くのですが 複数起動するとファイルの書き込みが行われなくなってしまいます。 ロックしたプログラム以外はロックエラーになり ロックについては正常に動いているように見えます。 なぜ書き込みが行われなくなってしまうかご教授いただけますか? import java.io.* ; import java.nio.*; import java.nio.channels.*; public class CopyFile { public static void main(String[] args) throws Exception { try{ FileInputStream fis = null; FileOutputStream output = null; FileChannel outChannel = null; FileLock outFileLock = null; byte buf[] = new byte[2048]; int len; int count = 0; if (args.length != 2) { System.out.println("使用法: java CopyFile ファイル名1 ファイル名2"); System.exit(0); } //if String source= args[0]; String target= args[1]; File sourceFile = new File(source); File targetFile = new File(target); fis = new FileInputStream(sourceFile); output = new FileOutputStream(targetFile); outChannel = output.getChannel(); outFileLock = outChannel.tryLock(); if (outFileLock == null) { System.out.println("rock error!!"); System.exit(0); } else { while ((len = fis.read(buf)) != -1) { output.write(buf, 0, len); count += len; } Thread.sleep(5000); output.flush(); output.close(); fis.close(); } }catch(Exception e){ System.out.println(e); } } } // Class CopyFile

    • ベストアンサー
    • Java
  • 文字コードの変換(Shift-JISからUTF8)

    文字コードがShift-JISのCSVファイルを読み込み、UTF-8のテキストファイルに出力するのに プログラムの中で変更しようとしているのですが、うまくいきません。出力ファイルの文字コードを 確認するとShift-JISのままです。 どなたか教えていただけないでしょうか? ActivePerl v5.16.0を使用し、Encodeモジュールのfrom_toを使用しています。 #!/usr/bin/perl use strict; use warnings; use utf8; use Encode; my $input_file="input.csv"; my $output_file="output.txt"; open (IN, $input_file) or die "$!"; open (OUT, ">$output_file") or die "$!"; while (<IN>){ chomp ($_); my @data=split(/,/,$_); for(my $i=0;$i<@data;$i++){ $data[$i]=Encode::from_to($data[$i],'shiftjis','utf8'); #Shift-JISからUTF-8に変換 $data[$i]=~s/\s+//g; print OUT $_; } print OUT "\n"; } close (IN); close (OUT);

    • ベストアンサー
    • Perl
  • UTF-8等のエンコードでテキストファイル書込

    Windowsデスクトップアプリケーション(C++)で簡易的なアプリを作っています。[OK]をクリックするとEditコントロールに入力されたテキストがテキストファイルとして保存されますが、メモ帳で開くと文字化けします。エンコードを変えて再度読み込んだところ、読み込むことができたエンコードはUTF-16 LEでした。 UTF-8等のエンコードで書き込みすることはできるんでしょうか。

  • テキストファイルからの読み込みについて

    度々の登場です。 外部テキストファイル内に ErrorMessage.txt ○○のエラーが発生しました △△のエラーが発生しました ■■のエラーが発生しました ・ ・ ・ ☆☆のエラーが発生しました --------------------------- と、そのプログラム内で発生する可能性のあるエラーメッセージを格納しておきます。 プログラム内で■■のエラーが発生したとします。 class Test{ public static void main(String[] args){ ・ ・ try{ ○○ }catch{ } try{ △△ }catch{ } try{ ■■ }catch{ } ・ ・ ・ try{ ☆☆ }catch{ } } } このとき 発生したエラーメッセージの内容をErrorMessage.txtから取得するにはどうしたらよいのですか? どうか、宜しくお願い致します。

    • ベストアンサー
    • Java
  • javaプログラム初心者です。

    入力ファイルの内容をWebサーバプログラムへ送信し、サーバからの応答を別ファイルに出力するクライアントプログラムを作っているのですが、出力ファイルにはなにも書き込みがされていません。(サーバからの応答は事前に不明でその長さが可変長である) 以下が作ったプログラムです。間違っているところを詳しくご指摘いただけるとありがたいです。お願いします。 import java.net.*; import java.io.*; public class client{ static final int BUFSIZE = 1792; public static void main(String[] args){ try{ String server = args[0]; //接続先のIPアドレス File file1 = new File(args[1]); //入力ファイル(HTTPリクエスト) FileReader filereader = new FileReader(file1); BufferedReader br = new BufferedReader(filereader); int serverport = Integer.parseInt(args[2]); //ポート番号 File file2 = new File(args[3]); //サーバからの応答をファイルに書き込む用 FileWriter filewriter = new FileWriter(file2); BufferedWriter bw = new BufferedWriter(filewriter); byte[] bytebuffer = new byte[BUFSIZE]; String str; while((str = br.readLine()) != null){ //入力ファイルの内容を1行ずつ読み込む bytebuffer = str.getBytes(); //入力ファイルの文字列をバイトに変換 } Socket socket = new Socket(server,serverport); //ソケットの生成 System.out.println("Connected to server...sending echo string"); InputStream in = socket.getInputStream(); //入出力ストリームの取得 OutputStream out = socket.getOutputStream(); out.write(bytebuffer); //文字列を送信 int receive; while((receive = in.read(bytebuffer))!=-1){ bw.write(new String(bytebuffer)); //サーバからの応答をファイルに出力 } bw.close(); socket.close(); }catch(IOException e){ } } }

  • Javaのプログラムについて教えてください!

    BufferedWriterを使ってコマンドプロンプトから文字を入力して実行時に与えたパスのテキストに書き込んでいくプログラムをコーディングしてみたのですがなかなか上手くいきません。添削をお願いします。 import java.io.*; class BW{ public static void main(String[] args){ try{ File fl = new File("args[0]"); FileWriter fw = new FileWriter(fl); BufferedWriter bw = new BufferedWriter(fw); for(int i = 0;args[i]==null;i++){ bw.write(args[i]); bw.newLine(); } bw.flush(); bw.close(); }catch(IOException e){ e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • ファイル転送が正常に動作しない

    サーバ側からクライアント側へファイル転送をJavaで行おうとしています。 そこで以下のようなプログラムを作成し、実行するのですが 実行自体はうまくいき、1つめのファイルはきちんと転送できるのですが、 2つめのファイルが転送完了後に確認すると0バイトとなっており、 きちんと動作しません。どうするべきでしょうか。 サーバ側 ※上でソケットはつないであります。 if(command.equals("put.") == true){ System.out.println("putモードに入りました"); // カーネル(linux.uml)の送信 String filename1 = args[1]; byte[] data1 = new byte[1024]; //ストリームの作成 FileInputStream fin1= new FileInputStream(filename1); BufferedOutputStream out2 = new BufferedOutputStream(sock.getOutputStream()); System.out.println("送信ファイル : " + filename1); //int totalSize1 = 0; int len1; while((len1 = fin1.read(data1)) != -1){ out2.write(data1); } out.flush(); fin1.close(); System.out.println(filename1 + "を送信完了しました"); // ルートファイルシステム(uml-root-hardy)の送信 String filename2 = args[2]; byte[] data2 = new byte[1024]; //ストリームの作成 FileInputStream fin2 = new FileInputStream(filename2); //ファイルの内容を読み出し、送信する System.out.println("送信ファイル" + filename2); //long totalSize2 = 0; long len2 = 0; while((len2 = fin2.read(data2)) != -1){ out2.write(data2); } out.flush(); fin2.close(); System.out.println(filename2 + "を送信完了しました"); } クライアント側 ※上でソケットはつないであります。 if(change.equals("put.") == true){ System.out.println("putモードに入りました"); // 2つのファイルを転送する // カーネル(linux.uml)の転送 String filename1 = args[2]; System.out.println("受信するファイル : " + filename1); // FileOutputStreamの作成 FileOutputStream fout1 = new FileOutputStream(filename1); BufferedInputStream in2 = new BufferedInputStream(sock.getInputStream()); int recvMsgSize1; int bufSize = 1024; byte[] byteBuffer1 = new byte[bufSize]; //int totalByte1 = 0; while((recvMsgSize1 = in2.read(byteBuffer1)) != -1){ fout1.write(byteBuffer1); } System.out.println(filename1 + "を受信完了しました"); fout1.close(); // ルートファイルシステム(uml-root-hardy)の転送 String filename2 = args[3]; System.out.println("受信するファイル : " + filename2); FileOutputStream fout2 = new FileOutputStream(filename2); long recvMsgSize2; //byte[] byteBuffer = new byte[bufSize]; byte[] byteBuffer2 = new byte[bufSize]; //long totalByte2 = 0; while((recvMsgSize2 = in2.read(byteBuffer2)) != -1){ fout2.write(byteBuffer2); } System.out.println(filename2 + "を受信完了しました"); fout2.close(); } またプログラム中では、サーバ、クライアントでそれぞれ len1,len2(サーバ側)、recvMsgSize1,recvMsgSize2(クライアント側) に警告で「ローカル変数len1(recvMsgSize1)は読み取られません」 と出ています。 どのように解決するべきでしょうか。

    • ベストアンサー
    • Java
  • 文字操作(エンコード)について

    基礎的な質問ですがよろしくお願いします。 <内容> 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.上記のような問題について勉強できるサイトがあれば教えてください。

    • ベストアンサー
    • Java
  • Javaでファイル転送プログラム

    Javaを用いてファイル転送プログラムを作成しています。 http://d.hatena.ne.jp/rintaromasuda/20060327/1143412352 を参考に作成したのですが、うまく転送できません。 プログラムは以下の通り。 ◎サーバ側 import java.net.*; import java.io.*; public class UMLFileServer { public static void main(String[] args) throws IOException{ if (args.length != 2) throw new IllegalArgumentException("An argument should be port and filename"); int servPort = Integer.parseInt(args[0]); String filename = args[1]; System.out.println("Output file name : " + args[1]); //Create FileOutputStream FileOutputStream fout = new FileOutputStream(filename); //Create ServerSocket ServerSocket servSock = new ServerSocket(servPort); int recvMsgSize; //int bufSize = servSock.getReceiveBufferSize(); int bufSize = 32; System.out.println("Size of ReceiveBuffer : " + bufSize); //Socket accepting loop while(true){ System.out.println("Wait for accepting... "); Socket clntSock = servSock.accept(); byte[] byteBuffer = new byte[bufSize]; System.out.println("Accepted client at " + clntSock.getInetAddress().getHostAddress() + " on port " + clntSock.getPort()); //Create InputStream InputStream in = clntSock.getInputStream(); //Read message and print it out int totalByte = 0; while((recvMsgSize = in.read(byteBuffer)) != -1){ System.out.println("Message : " + new String(byteBuffer,0,recvMsgSize)); System.out.println("Size : " + recvMsgSize); //Write to file totalByte = totalByte + recvMsgSize; fout.write(byteBuffer,0,recvMsgSize); } System.out.println("Recieved file size : " + totalByte); clntSock.close(); fout.close(); fout = null; } } } ◎クライアント側 import java.net.*; import java.io.*; public class UMLFileClient { public static void main(String[] args) throws IOException{ if (args.length != 3) throw new IllegalArgumentException("Arguments should be host,port and filepath"); String server = args[0]; int serverPort = Integer.parseInt(args[1]); String filename = args[2]; byte[] data = new byte[32]; //ソケットの作成 Socket socket = new Socket(server,serverPort); System.out.println("Connected to server"); //ストリームの作成 FileInputStream fin = new FileInputStream(filename); OutputStream out = socket.getOutputStream(); //ファイルの内容を読み出し、送信する System.out.println("Sending file : " + filename); int totalSize = 0; int len = 0; while ((len = fin.read(data)) != -1) { totalSize = totalSize + len; System.out.println(new String(data,0,len)); out.write(data, 0, len); } fin.close(); fin = null; System.out.println("size of file : " + totalSize); socket.close(); } } ◎実行結果 Output file name : hiroyasu.txt Size of ReceiveBuffer : 32 Wait for accepting... Accepted client at 192.168.71.104 on port 36608 Recieved file size : 0 Wait for accepting... 以上です。どなたか解決方法をご教授ください。

    • ベストアンサー
    • Java
  • 固定長データのbyteスキップについて

    バイナリ入出力でご質問がございます。 下記の例のように各レコードにある 先頭5byte付与されたデータを スキップ(破棄)して 各レコード10byteずつ読み込みたいのですが なにかサンプルデータもしくは アドバイス頂けないでしょうか? どうぞよろしくお願い致します。 例 1レコード 10byte (先頭5byte付与) LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 ↓ 1234567890 1234567890 1234567890 1234567890 1234567890 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.io.ByteArrayOutputStream; public class dat{ public static void main(String[] args) { String inputFileName = ""; String outputFileName = ""; // ファイルオブジェクトの生成 File inputFile = new File(inputFileName); File outputFile = new File(outputFileName); try { FileInputStream fis = new FileInputStream(inputFile); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream(outputFile); BufferedOutputStream bos = new BufferedOutputStream(fos); byte[] buf = new byte[17]; int len = 0; while ((len = bis.read(buf, 0, 17)) == 17) { bos.write(buf, 0, 17); } bos.flush(); bos.close(); bis.close(); } catch(Exception e) { e.printStackTrace(); } }

    • ベストアンサー
    • Java