• ベストアンサー

バイト配列 unicode

java初心者です。 以下のソースコードの 「new String(strVal.getBytes("ISO-8859-1"),"JISAutoDetect」 の部分の意味が分からなくこまっています。 <%@ page import="java.io.*" %> <%! public String strEncode(String strVal) throws UnsupportedEncodeingExcception{ if(strVal==null){ return null; }else{ return new String(strVal.getBytes("ISO-8859-1"),"JISAutoDetect")); } } %> そもそも 「バイト配列とは何か」 「なんで必要なのか?」 など、わかりやすく説明していただけると幸いです。

  • Java
  • 回答数1
  • ありがとう数0

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

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

文字コードについてどの程度の知識をお持ちですか。 JavaのStringやcharで使われている文字コードは1文字=16ビット(2バイト)の固定長です (Unicodeのバージョンが上がってこの原則は一部崩れてしまいましたが)。'A'という文字も'亜'という文字も16ビットの値で表されます。 一方、世の中で広く使われている文字コードでは1文字を表すのに8ビット(1バイト)、16ビット(2バイト)、24ビット(3バイト)などが混在しています。たとえばShift_JISでは'A'は1バイト、'亜'は2バイトですし、UTF-8では'A'は1バイト、'亜'は3バイトで表されます。このような文字コードのデータをStringやcharで扱うのは不便なので、byteの配列に入れて扱います。 Shift_JISのbyte配列 ←→ Java String ←→ UTF-8のbyte配列 JavaのStringから各文字コードのbyte配列を得るにはgetBytes()を使用し、逆にbyte配列からStringを作るにはnew String(byte配列、エンコーディング名)を使います。 基本は上記の通りなのですが、ご質問の「new String(strVal.getBytes("ISO-8859-1"), "JISAutoDetect")」というのはさらに特殊な使い方です。 おそらく、strValには「文字コードを正しく設定できなかった日本語文字列のデータ」が入っているのでしょう。それを一度byte配列に戻してから"JISAutoDetect"で文字コードを判定して改めてStringに変換しているのだと思われます。getBytes("ISO-8859-1")の部分で余計におかしくならないかが心配ですが。

関連するQ&A

  • UTF-8で書かれたJSPの日本語文字コード変換の正しい方法がわかりません

    nagilumと申します。 「10日でおぼえるJSP/サーブレット 入門教室」という、2002年に発売された ちょっと旧い本で勉強をしています。 下記はその中のJSPのコードで、クライアント(ウェブブラウザ)から受け取った 文字列をハッシュのキーとして検索して、値の内容を表示するものです。 ウェブブラウザから正しい(ハッシュに存在するキー)文字列を入力しても、 ハッシュのキーにヒットしません。 日本語の文字コードの問題のようですが、下記のコードをどのように修正すれば よいのかわかりません。 すみません、助けてください。 クライアント(ウェブブラウザ)は Windows (Shift_JIS) です。 サーバ(Apache+Tomcat)は Fedora Core 4 (UTF-8) です。 よろしくお願いします。 1 <%@ page contentType="text/html;charset=UTF-8" import="java.util.*,java.io.*" %> 2 <%! 3 public String strEncode( String strVal ) throws UnsupportedEncodingException { 4 if( strVal == null ){ 5 return null; 6 } 7 else { 8 return new String( strVal.getBytes( "ISO-8859-1" ), "JISAutoDetect" ); 9 } 10 } 11 %> 12 <html> 13 <head> 14 <title>アドレス帳検索(検索結果)</title> 15 </head> 16 <body> 17 <h1 style="background:#cccccc">アドレス帳検索</h1> 18 <% 19 HashMap hm = new HashMap(); 20 hm.put( "輪笠貴子", "女, 0xx-xxx9-1111,横浜市まるばつ町5-18-199" ); 21 hm.put( "佐々木健司", "男,04x-231x-xxxx,川崎市まるまる町1-3213" ); 22 hm.put( "鳥内都", "女,09x-21xx-xx97,横浜市なになに区5-16" ); 23 hm.put( "金崎瑞穂", "女,02x-654x-324x,相模原市なんとか区1-9-21" ); 24 String strName = strEncode( request.getParameter( "name" ) ); 25 if( hm.containsKey( strName ) ){ 26 String strResult = (String)hm.get( strName ); 27 StringTokenizer tkn = new StringTokenizer( strResult, "," ); 28 %> 29 <dl> 30 <dt style="font-size:14pt;font-weight:bold"> 31 <%= strName %> 32 </dt> 33 <dd> 34 <ol> 35 <li><%= tkn.nextToken() %></li> 36 <li><%= tkn.nextToken() %></li> 37 <li><%= tkn.nextToken() %></li> 38 </ol> 39 </dd> 40 </dl> 41 <% 42 } 43 else { 44 %> 45 <div style="color:Red">指定された名前は見つかりませんでした</div> 46 <% 47 } 48 %> 49 </body> 50 </html> ↑きちんと整形したコードをペーストしたのですが、 ブランクが全部削られてしまってとても読みにくくなってます。 ごめんなさい。

    • ベストアンサー
    • Java
  • 簡単な配列の作り方

    やりたいことがあるのですが、原始的なやり方しか思いつきません。 簡単な方法があればご教授願いたく思い質問いたしました。 よろしくお願いします! <やりたいこと> 明細行が5件ありまして、それぞれの行に有効かどうかフラグがある。 5件のうち有効になっている数だけの配列を作成する。 --------------------------------------------- 例1)1,2,3,4,5のうち2,3,5の3行が有効の場合   String[] str = String[]{2,3,5} 例2)1,2,3,4,5のうち4の1行が有効の場合   String[] str = String[]{4} --------------------------------------------- <現在やっていること> // 有効行の判断用 private boolean yukoFlg1 = false; private boolean yukoFlg2 = false; private boolean yukoFlg3 = false; private boolean yukoFlg4 = false; private boolean yukoFlg5 = false; // 有効行の数 private long yukoCnt = 0; /** * 該当行分の配列にする String[] * @param str 配列にしたい値 */ public String[] setStrArray ( String str1, String str2, String str3, String str4, String str5) throws Exception { String[] result = null; // 有効行の数が1の場合 if (yukoCnt == 1) { if (yukoFlg1) { result = new String[]{str1}; } else if (yukoFlg2) { result = new String[]{str2}; } else if (yukoFlg3) { result = new String[]{str3}; } else if (yukoFlg4) { result = new String[]{str4}; } else { result = new String[]{str5}; } // 有効行の数が2の場合 } else if (yukoCnt == 2) { if (yukoFlg1) { if (yukoFlg2) { result = new String[]{str1, str2}; } else if (yukoFlg3) { result = new String[]{str1, str3}; } else if (yukoFlg4) { result = new String[]{str1, str4}; } else { result = new String[]{str1, str5}; } } else if(yukoFlg2) { if (yukoFlg3) { result = new String[]{str2, str3}; } else if (yukoFlg4) { result = new String[]{str2, str4}; } else { result = new String[]{str2, str5}; } } else if (yukoFlg3) { if (yukoFlg4) { result = new String[]{str3, str4}; } else { result = new String[]{str3, str5}; } } else { result = new String[]{str4, str5}; } // 有効行の数が3の場合 } else if (yukoCnt == 3){ if (yukoFlg1) { if (yukoFlg2) { if (yukoFlg3) { result = new String[]{str1, str2, str3}; } else if (yukoFlg4) { result = new String[]{str1, str2, str4}; } else { result = new String[]{str1, str2, str5}; } } else if (yukoFlg3) { if (yukoFlg4) { result = new String[]{str1, str3, str4}; } else { result = new String[]{str1, str3, str5}; } } else { result = new String[]{str1, str4, str5}; } } else if (yukoFlg2) { if (yukoFlg3) { if (yukoFlg4) { result = new String[]{str2, str3, str4}; } else { result = new String[]{str2, str3, str5}; } } } else { result = new String[]{str3, str4, str5}; } // 有効行の数が4の場合 } else if (yukoCnt == 4) { if (!yukoFlg1) { result = new String[]{str2, str3, str4, str5}; } else if (!yukoFlg2) { result = new String[]{str1, str3, str4, str5}; } else if (!yukoFlg3) { result = new String[]{str1, str2, str4, str5}; } else if (!yukoFlg4) { result = new String[]{str1, str2, str3, str5}; } else { result = new String[]{str1, str2, str3, str4}; } // 有効行の数が5の場合 } else { result = new String[]{str1, str2, str3, str4, str5}; } return result; }

    • ベストアンサー
    • Java
  • Stringオブジェクトの文字コードの変換

    NewString = new String(b.getBytes("iso-8859-1"),"Shift_JIS"); でShift-Jisに変換できるとありましたが、どうも出力の 日本語部分が3Fになってしまってうまくいきません。 テスト用に以下のコードを作ってみました。 import java.io.File; import java.io.FileWriter; import java.io.BufferedWriter; import java.io.IOException; import java.io.FileOutputStream; public class Test { public static void main(String[] args) { try{ String regex_title; regex_title = "制限をしている場合"; System.out.println(getHexString(regex_title.getBytes())); System.out.println(getHexString(regex_title.getBytes("iso-8859-1"))); regex_title = "制限をしている場合"; regex_title = getUTF8(regex_title); System.out.println(getHexString(regex_title.getBytes())); System.out.println(getHexString(regex_title.getBytes("iso-8859-1"))); regex_title = "制限をしている場合"; regex_title = getShiftJIS(regex_title); System.out.println(getHexString(regex_title.getBytes())); System.out.println(getHexString(regex_title.getBytes("iso-8859-1"))); FileOutputStream fs = new FileOutputStream("./test.txt"); fs.write(regex_title.getBytes()); fs.close(); }catch(Exception ex){ } } public static String getHexString(byte[] b){ String buff=""; try{ for(int i=0;i<b.length;i++) buff += String.format("\\x%02x", b[i]); }catch(Exception ex){ } return buff; } public static String getUTF8(String b){ try { //UTF-8へ変換 return new String(b.getBytes(), "UTF-8"); } catch (Exception e) { e.printStackTrace(); return b; } } public static String getShiftJIS(String b){ try { //UTF-8へ変換 return new String(b.getBytes(),"Shift_JIS"); } catch (Exception e) { e.printStackTrace(); return b; } } // @Override } //////////////////////////////////////////////////////////// 1. System.out.println(getHexString(regex_title.getBytes("iso-8859-1"))); の部分の出力をみると3Fに変換されています。 regex_title.getBytes("iso-8859-1")の時点で3Fな事がわかります。 何故でしょうか? 私がやりたい事はStringの内部のコードをUTF8にする事です。 NewString = new String(b.getBytes("iso-8859-1"),"UTF-8"); では、出来ていないようでした。 2. また、以下のコードを実行するとtest.txt test2.txtともに 文字コードがShiftJisで出力されるのはなぜでしょうか? 変換を行わなければ内部処理形式のUnicodeで出力されるの ではないのでしょうか? regex_title = "制限をしている場合"; FileOutputStream fs = new FileOutputStream("./test.txt"); fs.write(regex_title.getBytes()); fs.close(); File file = new File("./test2.txt"); BufferedWriter bw = new BufferedWriter(new FileWriter(file)); bw.write(regex_title); bw.close(); 上はgetBytes()が変換してるのでしょうか? 下はBufferedWriterかFileWriterが変換してる? ではString内部のByteをそのまま出力するにはどうしたら・・・。

    • ベストアンサー
    • Java
  • 配列で指定した文字の表示の仕方。

    JAVAアプレットで 配列にて private String[][] A = {"☆A", "☆B", null}; {"☆あ", "☆い", "☆う"}; {"☆1", null, null}; と指定したあとに 各配列をアプレット上に ☆A ☆B ↓ ☆あ ☆い ☆う ↓ ☆1 といった順番で表示させたいです。 そこでinitメソッドにて、パネルをGridLayout(3,1)と各パネルを作り 各パネルをaddで加えていきます。 ここて各パネルをP1,P2,P3とします。 表示の仕方は P1.setText(A[page][0]); if(A[page][1] == null){page++;} else{ P2.setText(A[page][1]); if(A[page][2] == null){page++;} else{ P3.setText(A[page][2]); page++; } } としました。 pageとは各配列Aを順に表示させる為の変数です。 しかしこの方法だと ☆A ☆B ↓ ☆あ ☆い ☆う ↓ ☆1 ☆い ☆う と表示されてしまいます。 目標としてる表示の仕方にしたいのですが、一体どこがいけないのでしょうか。

    • ベストアンサー
    • Java
  • javaでクッキーを取得したい

    以下ソースで、ホームページのデータは取得できるのですが、クッキーが必要なページではうまく作動しません。 どのように改良すればよいでしょうか? また、こういったプログラムを作るのに参考になる書籍をご存知でしたら教えてください。 よろしくお願いいたします。 import java.io.*; import java.net.*; class test { public static void main(String[] args) throws Exception { URL url = null; BufferedReader in = null; String readString = null; url = new URL("http://www.yahoo.co.jp"); in = new BufferedReader(new InputStreamReader(url.openStream(),"JISAutoDetect")); while((readString=in.readLine())!=null) System.out.println(readString); in.close(); } }

    • ベストアンサー
    • Java
  • javaのエンコードについて?

    下記のプログラムでホームページの情報は読み取ることができるようになったのですが、一部ホームページ(UTF-8エンコードのホームページと思われる)、文字化けを起こして見ることができません。 解決する方法を、教えていただけないでしょうか? おねがいいたします。 import java.io.*; import java.net.*; class test{ public static void main(String[] args) throws Exception { URL url = null; BufferedReader in = null; String readString = null; url = new URL("http://www.faireal.net/"); in = new BufferedReader(new InputStreamReader(url.openStream(),"JISAutoDetect")); while((readString=in.readLine())!=null) System.out.println(readString); in.close(); } }

    • ベストアンサー
    • Java
  • parameterのunicode変換

    unicode変換について聞かせてください。 servletでparameterを受け取って、unicode変換させて、自分の 必要なparameterだけを使うということです。 いろいろHPなどを参考に調べた結果、 Hashtable data = new Hashtable(); Enumeration e = request.getParameterNames(); while (e.hasMoreElements()) { String key = (String)e.nextElement(); String[] values = request.getParameterValues(key); try { data.put(key,new String(values[0].getBytes("8859_1"),"JISAutoDetect")); } catch(java.io.UnsupportedEncodingException ex) { } } との内容の変換を元に考えたのですが、自分では改造できずにいます。 上記の例では、Hashtableに収められた、変換内容の取得が、 String hinmei = (String)data.get(kye); などとすると、hinmeiのunicode変換された値がすべて取得される と思います。 しかし、自分の欲しいunicode変換された値だけを取得するには どのようにしたらよいでしょうか? 例えば、 String hinmei = (String)data.get(hinmei); String hinban = (String)data.get(hinban); というように、個別で取得したいのです。 もちろん、この他にも、parameterで送られてきている値は、あるかも 知れませんが、この場合は使わず・・・。 また、使うときには、 String hinmoku = (String)data.get(hinmoku); と追加するだけでいいようにしたいのです。 ご教授できらた幸いです。

    • ベストアンサー
    • Java
  • 二次元配列について

    csvファイルを読み込み 、(コンマ)毎に区切り出力するプログラムを今作っています。 そこで最初に import java.io.*; import java.util.*; public class aaa { public static void main(String aaa[]) throws Exception{ Scanner yomi = new Scanner( new File("C:\\addorres.csv") ); yomi.useDelimiter( "," ); List<String> adorr = new ArrayList<String>(); while( yomi.hasNext() ){ adorr.add( yomi.next() ); } for( String s: adorr ){ System.out.println( s ); } } } と打ちましたそうすると csvに 名前、住所、電話、アドレス、ID、PW 名前、住所、電話、アドレス、ID、PW 名前、住所、電話、アドレス、ID、PW と入っていると表示されるのは 名前 住所 電話 アドレス ID PW 住所 電話 アドレス ID PW 住所 電話 アドレス ID PW となってしまって名前を取り出すことができません。 そこで最初は名前入っていたんだからと安直に二次元配列に変えることにしました。 import java.io.*; import java.util.*; public class aaa { public static void main(String aaa[]) throws Exception{ String[][] ad = new String[9999][9999]; int a = 0,c = 0,d=0; Scanner yomi = new Scanner( new File("C:\\addorres.csv") ); yomi.useDelimiter( "," ); List<String> adorr = new ArrayList<String>(); while( yomi.hasNext() ){ adorr.add( yomi.next() ); } for( String s: adorr ){ if(a==5) { c++; a=0; ad[a][c] = s; d++; }else{ ad[a][c]= s; a++; d++; } } a = 0; c = 0; for (int b=0;b<d;b++) { if(a==5) { c++; a=0; System.out.println(b+":"+ad[a][c]); }else{ System.out.println(b+":"+ad[a][c]); a++; } } } } そこでこの様に打ったんですが実行すると Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at aaa.main(aaa.java:7) と結果がこの様にエラーとして返ってきます。 どなたかこれを解決する方法又は1次元配列でも名前を表示させる方法がわかる方がいましたら お願い致します。

    • ベストアンサー
    • Java
  • 文字化け

    JSPで取ったデータをServletがGetParameterしています。 文字化け防止のコーディングは以下のようにしています。 String adr = request.getParameter("adr"); //住所 if(adr !=null && adr.equals("")==false){ //文字化け防止(日本語変換) adr = new String(adr.getBytes("8859_1"), "JISAutoDetect"); }else{ adr = ""; } が、全角のハイフン(-)だけが 文字化けしてしまいます。 ?になってしまいます。 なにかいいページかヒントがありましたら 教えてください。

  • Javaで外部ファイルの実行

    Javaで外部ファイルの形態素解析ツールのjumanを実行させようとしてるのですが上手くいきません。 ソースは以下のようにしています。 public class CommandExec { /** * 外部コマンドを実行します。 * またリタンーン値で、標準出力、エラー出力 、リターンコードを取得します。 * 例: * execCommand("notepad.exe"); * * @see execCommand(String[] cmds) * ※実行するコマンドに引数(パラメータ)がある場合は、 * 以下を使用してください。 * @param cmd 実行するコマンド * @return コマンド実行結果情報を保持するString配列 * 配列[0] ⇒ 標準出力 * 配列[1] ⇒ エラー出力 * 配列[2] ⇒ リターンコード * @throws IOException 入出力エラーが発生した場合 */ String b; public static String[] execCommand(String cmd) throws IOException, InterruptedException { return execCommand(new String[] { cmd }); } /** * 外部コマンドを引数(パラメータ)を指定して実行します。 * またリタンーン値で、標準出力、エラー出力 、リターンコードを取得します。 * 例: * execCommand(new String[]{"notepad.exe","C:\test.txt"}); * * Process.waitFor()を実行していますので、外部コマンドの実行が * 終了するまでこのメソッドは待機します。 * * @see execCommand(String cmd) * ※実行するコマンドに引数がない場合は簡易的にこちらを * 使用してください。 * @param cmds 実行するコマンドと引数を含む配列 * @return コマンド実行結果情報を保持するString配列 * 配列[0] ⇒ 標準出力 * 配列[1] ⇒ エラー出力 * 配列[2] ⇒ リターンコード * @throws IOException 入出力エラーが発生した場合 */ public static String[] execCommand(String[] cmds) throws IOException, InterruptedException { String[] returns = new String[3]; String LINE_SEPA = System.getProperty("line.separator"); Runtime r = Runtime.getRuntime(); Process p = r.exec(cmds); InputStream in = null; BufferedReader br = null; try { in = p.getInputStream(); StringBuffer out = new StringBuffer(); br = new BufferedReader(new InputStreamReader(in,"sjis")); String line; while ((line = br.readLine()) != null) { out.append(line + LINE_SEPA); System.out.println(line); } System.out.print("\n"); returns[0] = out.toString(); br.close(); in.close(); in = p.getErrorStream(); StringBuffer err = new StringBuffer(); br = new BufferedReader(new InputStreamReader(in)); while ((line = br.readLine()) != null) { err.append(line + LINE_SEPA); } returns[1] = err.toString(); returns[2] = Integer.toString(p.waitFor()); return returns; } finally { if (br != null) { br.close(); } if (in != null) { in.close(); } } } public static void main(String[] args) throws IOException, InterruptedException { ArrayList a = new ArrayList(); CommandExec.execCommand(new String[]{"C:\\Program Files\\juman\\juman.exe","<","C:\\Program Files\\juman\\test1.txt"}); } } これをおなじ解析ツールのchasenを実行した場合は上手くいくのですがなぜでしょうか? chasenの場合は以下のようにしてます。 CommandExec.execCommand(new String[]{"C:\\Program Files\\ChaSen\\chasen.exe","C:\\Program Files\\Chasen\\test1.txt"}); よろしくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう