程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> J2ME中文的支持問題

J2ME中文的支持問題

編輯:J2ME

在使用MotoJ2SDK進行J2ME應用程序的開發,經常會遇到中文的顯示,存儲,傳輸和編碼的問題。首先要對388手機上開發KJava程序時,對於中文的支持情況有所了解。
          中文的支持有三種編碼方式:
          -ISO10646 and ISO8859_1 編碼格式;
          -UTF8編碼格式;
          -UNICODE
          下面我們來看一下各種不同的編碼方式有什麼區別。在目錄Text下有三個.txt文件,它們是分別用ANSI、UNICODE、UTF8方式編碼的一段中文,內容為“摩托羅拉”。我們用UltraEdit分別打開三個文件,並且用HEX方式浏覽,可以發現:
          1. ANSI方式的16進制數據為
          C4,A6,CD,D0,C2,DE,C0,AD,
          其中每個中文占兩個字節,並且每個字節都大於0xA0
          2. UNICODE方式的16進制數據為
          FF,FE,69,64,58,62,57,7F,C9,62
          其中頭兩個字節“FF,FE”是固定的,表示該文本按照UNICODE編碼,並且隨後為每個中文占兩個字節。
          3. UTF8方式的16進制數據為
          EF,BB,BF,E6,91,A9,E6,89,98,E7,BD,97,E6,8B,89
          其中頭3個字節“EF,BB,BF”是固定的,表示該文本按照UTF8編碼,並且隨後為每個中文占3個字節。

          但是,僅了解這些,對於開發有關中文的應用程序還是不夠的。如何能夠保證正確的傳輸和存儲中文才是根本目的。經常有些開發者會遇到中文無法存儲,以及經過網絡傳輸後得到的是亂碼的問題。這是因為,J2ME中通常是不能對中文直接進行存儲和傳輸的,要進行一定的轉換。在Hopen的J2ME論壇中,有人提到這樣的方法,即用以下兩個函數把字符串先轉成byte 數組後在寫入數據庫,在讀出時也要先把byte數組轉換成字符串,再進行顯示等操作。
          public static String byte2string(byte[] b,int offset,int len )
          {
          try{
          ByteArrayInputStream bais = new ByteArrayInputStream(b,offset,len);

     DataInputStream inputstream = new DataInputStream( bais );
          return inputstream.readUTF();
          }catch(IOException e){return null;}
          }
          public static byte[] string2byte(String s)
          {
          try{
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          DataOutputStream outputstream = new DataOutputStream(baos);
          outputstream.writeUTF( s );
          return baos.toByteArray();
          }catch(IOException e){return null;}
          }

          經過試驗,發現這是一種簡單有效的方法,並且同樣使用於UDP傳輸中文數據,即再傳輸前先轉換成byte數組,接收後把byte數組再轉換成字符串顯示。在目錄UTFTest中,我做了一個簡單的實例。UTFSendTest.Java中,通過TextBox輸入一段要傳輸的中文,
          String strText=mainScreen.getString();
          然後定義一個byte數組,
          byte[] bText = new byte[100];
          然後把要發送的字符串利用前面的函數轉換成byte數組,以便進行傳輸
          bText = string2byte(strText);
          int length = bText.length;
          最後把轉換後的byte數組數據發送到Server端,
          dc = (DatagramConnection)Connector.open(destAddr);
          Datagram dobject = dc.newDatagram(bText,length,destAddr);
          dc.send(dobject);
          在Server端的UTFTest.Java中做一個逆過程即可,
          dc = (DatagramConnection)Connector.open("datagram://:"+ port);
          Datagram dobject;
          byte[] bReceive = new byte[100];
          dobject = dc.newDatagram(dc.getMaximUMLength());

  dc.receive(dobject);
          bReceive = dobject.getData();
          String strReceive = byte2string(bReceive,0,bReceive.length);
          mainScreen.setString("已收到:"+strReceive);

          現在似乎有了一個權宜之計,至少可以進行有關中文的操做了。但是有關中文的問題還沒有徹底的說清楚。還有一個經常提到的問題,就是為什麼不能象顯示英文一樣,用System.out.println(strReceive); 來顯示一段中文字符串變量呢?這一點對於本來就不直觀的調試界面來說也是十分必要的,開發者要經常通過這種方式來驗證中文是否讀取和傳輸正確。而實際上,我們看到的只是一串無奈的“???”。因此在MotoJ2SDK中,直接用
          System.out.println ("中文");
          或者是,String testString = new String("中華人民共和國");
          System.out.println(testString);
          通常是不可行的。如何才能保證在模擬器界面和system.out中都能正確顯示中文呢?下面我們以finalUDP目錄中的UDPServer和UDPClIEnt為例來分析一下。
          如果采用上面的方法,利用函數byte2string()和 string2byte(),在進行傳輸之前都轉換成Byte數組的格式,用 UTF8的編碼方式,可以得到正常的傳輸,Client端發出“發送摩托羅拉”,Server端收到後發出“返回摩托羅拉”,ClIEnt端接收到後顯示在模擬器手機屏幕上,但是發送和接收中文字符串用System.out.println()時,都是“???”。
          下面對程序做如下改動,Server端受到“發送摩托羅拉”後,要發出“返回摩托羅拉”。但是這次不采用
          static final String replyMsg=”返回摩托羅拉”;
          byte[] bText = new byte[100];
          bText = string2byte(replyMsg);
          而是分別用bText =replyMsg.getBytes();
          或 bText =replyMsg.getBytes("ISO10646");
          或 bText =replyMsg.getBytes("ISO8859_1");
          把待發字符串轉換成字符數組,在ClIEnt端接收時不用以前的方式:
          dc.receive(dobject);

  bReceive = dobject.getData();
          receiveMsg = byte2string(bReceive,0,bReceive.length);
          而是直接采用
          dc.receive(receiveData);
          receiveMsg = new String(receiveData.getData(),0,receiveData.getLength());
          然後再把接收到字符串顯示輸出,為了細致分析接受到的字符數組每個元素的值,用如下方式讀出並顯示:
          bReceive=receiveMsg.getBytes();
          for(int i=0;i<bReceive.length;i++)
          System.out.println("rcv"+i+":"+bReceive[i]);
          經過試驗,bText =replyMsg.getBytes();三種不同的參數情況,試驗結果如下表所示:



          參數情況 接收到的數組 元素情況 接收端模擬器 屏幕顯示情況 接收端system.out 顯示情況
          Void 共12個bytes,每個漢字對應2個bytes,
          並且值即為各自ANSI編碼值,例如“返”對應0xB7,0xB5  亂碼 正常
          "ISO10646" Java.io.unSupportedEncodingException:ISO10646    
          "ISO8859_1" 共6個元素,每個均為0x3F, 即為“?

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved