Android中类型转换好像支持不是太好,备份下有用的类型转换函数和工具函数.

一、类型转换

1.byte 转 int  ( int 可以再转成long double float )

1.public static int byteToInt(byte[] data, int offset) 
 2.{  
 3.        int result = 0;  
 4.    int n1, n2, n3, n4;  
 5.      
 6.    n1 = data[offset + 3] & 0xFF;  
 7.    n2 = data[offset + 2] & 0xFF;  
 8.    n3 = data[offset + 1] & 0xFF;  
 9.    n4 = data[offset] & 0xFF;  
 10.          
 11.    result = n1 << 24  | n2 << 16 | n3 << 8 | n4;  
 12.          
 13.    return result;  
 14.}


2. byte 转 Hex

1.public static String toHexString(byte[] b)   
 2.{  
 3.    char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',  
 4.                  'A', 'B', 'C', 'D', 'E', 'F' };  
 5.          
 6.        StringBuilder sb = new StringBuilder(b.length * 2);  
 7.        for (int i = 0; i < b.length; i++)  
 8.        {  
 9.            sb.append(HEX_DIGITS[(b[i] & 0xf0) >> 4]);  
 10.            sb.append(HEX_DIGITS[b[i] & 0x0f]);  
 11.        }  
 12.        return sb.toString();  
 13.} 
 3. HexString 转 long1.public static long hexStringToLong(String s)  
 2.{  
 3.    String serial = "0123456789ABCDEF";  
 4.                  
 5.    s = s.trim().toUpperCase();  
 6.    if( s.length() > 8 ) return 0;  
 7.          
 8.    long num = 0;  
 9.    int  len = s.length();  
 10.          
 11.    for( int i = 0; i < len; i++)  
 12.    {  
 13.        num += (serial.indexOf( s.charAt(i) ) << (4 * (len - i - 1)));  
 14.    }  
 15.          
 16.    return num;  
 17.}

 

Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并
且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
byte[]是字节数组类型,和int[]类似,只是一个是字节型的,一个是整型的;
char是UNICOEDE字符,为16位的整数;
String是个类,一般用来表示字符串的;
hello.getBytes()意思就是把hello这个字符串转化为字节流(byte型);一般前面加个byte[]型的变量,就是把转
化后的字节流放到这个变量里,如下:

byte[] bt=hello.getBytes();
// char转byte
private byte[] getBytes (char[] chars) {
    Charset cs = Charset.forName ("UTF-8");
    CharBuffer cb = CharBuffer.allocate (chars.length);
    cb.put (chars);
    cb.flip ();
    ByteBuffer bb = cs.encode (cb);
    return bb.array();
  }
 // byte转char
 private char[] getChars (byte[] bytes) {
       Charset cs = Charset.forName ("UTF-8");
       ByteBuffer bb = ByteBuffer.allocate (bytes.length);
       bb.put (bytes);
       bb.flip ();
       CharBuffer cb = cs.decode (bb);
    return cb.array();
 } 
1.string 转 byte[]
 
byte[] midbytes=isoString.getBytes("UTF8");
 
//为UTF8编码
 
byte[] isoret = srt2.getBytes("ISO-8859-1");
 
//为ISO-8859-1编码
 
其中ISO-8859-1为单字节的编码


2.byte[]转string


String isoString = new String(bytes,"ISO-8859-1");
 
String srt2=new String(midbytes,"UTF-8");




说明:


在网络传输或其它应用中常常有同一的中间件,假设为String类型。因此需要把其它类型的数据转换为中间件的类型。


将字符串进行网络传输时,如socket,需要将其在转换为byte[]类型。这中间如果采用用不同的编码可能会出现未成预料的问题,如乱码。


下面举个例子:


我们用socket传输String类型的数据时,常常用UTF-8进行编码,这样比较可以避免一个“中文乱码”的问题。


发送端:


String sendString="发送数据";
 
byte[] sendBytes=  sendString .getBytes("UTF8");
 
.......socket发送
 
接受端:
 
String recString=new String(sendBytes ,"UTF-8");




但是,这里往往又会出现这样一个问题。就是想要发送的数据本身就是byte[]类型的。


如果将其通过UTF-8编码转换为中间件String类型就会出现问题


如:


byte[]
 
String sendString=new String( bytes ,"UTF-8");
 
 
byte[] sendBytes= sendString .getBytes("UTF8");


然后再发送


接受时进行逆向转换


String recString=new String( sendBytes ,"UTF-8");
 
byte[] Mybytes=isoString.getBytes("UTF8");
 
这时Mybytes中的数据将是[50, 0, -17, -65, -67, 28, -17, -65, -67]




因此,需要采用单字节的编码方式进行转换


String sendString=new String(  bytes ,"UTF-8");   改为       String sendString=new String(  bytes ,"ISO-8859-1" );
 
byte[] Mybytes=isoString.getBytes("UTF8");  改为   byte[] Mybytes=isoString.getBytes( "ISO-8859-1" );


这样所需要的字节就有恢复了。

现在UNICODE规定了一个字符必须由2个8位数字来表示,想想,8x8x8x8x = 65536 ,是多大的一个数字啊!所以
全世界的文字才能都包含进去。当然拉,也有人说中国字可能都不止6万个拉,还要包括别的文字,但人家外国
人觉得你们中国人常用的也没那么多,所以就这么定了。
C语言的基本数据类型是没有字符串这个类型的,它只有char[]。也就是C把字符顺序放入一个字节数组就完了。
而且C也不管放在数组里的是什么文字,也不管那些字是按什么编码标准的。而且他的char的大小也不一定是8位
数字,有时候是16位也可能,这要看具体的机器和操作系统。所以写程序的人必须要知道正在处理的char[]的内
容到底是按什么编码表表示的字符串,要知道如果比较两国文字是否相同,可是没任何意义的哦!
String里的字符信息是用UNICODE编码存放的。而JAVA为了表示字符(注意是单个字符),也有char这个数据类型
,而且他的大小是固定2个8位16进制数字长度,也就是0~65535罗。为的就是对应UNICODE里面的一个字符。大家
如果想取一个String里的按UNICODE数字,可以用getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
方法取得一个char[],这个char[]里就是表示String字符的,按UNICODE编码表编码的数字。
现在绝大多数的系统和程序都不是按UNICODE来处理字符,而JAVA程序总是要和别的程序和系统交换数据的,所以在接
收一个字符,或者是发送一个字符的时候,就必须要留意当前系统和UNICODE的关系了。
JAVA按英文的编码表ASCII来处理这两个数字.通过new String({0xB5,0xB1})得到的String.用
new String({0xB5,0xB1},"GB2312")来处理,这时候新建立的String才真的是一个“当”字。
如何把“当”字用GB2312输出?String.getBytes("GB2312")就可以拉!所以有一点要记住:和外界交换任何信息都是以
byte[]来进行的!。你可以留意一下JAVA大多数的I/O类,都有以byte[]作为参数和返回值的方法。
java的char和byte,2种基本类型。
byte:字节,占8位(bit)二进制,能表示的最大数字为2的8次方,含正负,故范围为: -128...0...127
char:单字符型。由于java统一使用unicode编码来表示一个字符;unicode占2个字节(16位)。
char可以表示任意字符,含半角字母数字等,也可以表示中文。
如 char c1 = 'A';
  char c2 = '1';
  char c3 = '我';
由于半角字符比较特殊,来源于8位(1byte)Ascii码,也就是说1个字节就足够存储。在unicode中使用低8位(1byte)
就可以表示,高8位不使用也无所谓。存储到内存中就只占一个字节。
而中文就使用完整的16位unicode,存储到内存中就占2个字节。
java的String其实就是char[]的封装类型
转化为ASC码非常简单:
     

String str = "中华人民共和国";
System.out.println(str);
 byte[] b = str.getBytes();
 for (int i = 0; i < b.length; i++) {
System.out.print(Integer.toHexString(b[i] & 0xff) + " "); 
  }
  System.out.println();


       
       
linux下JNI实现
JNI是Java native interface的简写,可以译作Java原生接口。Java可以通过JNI调用C/C++的库。
用JNI实现一个经典的“Hello World”程序。该程序在Java中通过JNI调用c函数实现“Hello World”的输出。创建该程序分为以下步骤:
 下面我们就一步一步来实现这个程序。
创建HelloWorld.java

class HelloWorld
 {
  private native void print();
  public static void main(String[] args)
  {
   new HelloWorld().print();
  }
  static
  {
   System.loadLibrary("HelloWorld");
  }


}注意print方法的声明,关键字native表明该方法是一个原生代码实现的。另外注意static代码段的System.loadLibrary调用,这段代码
表示在程序加载的时候,自动加载libHelloWorld.so库。
编译HelloWorld.java
在命令行中运行如下命令:
javac HelloWorld.java在当前文件夹编译生成HelloWorld.class。
生成HelloWorld.h
在命令行中运行如下命令:
javah -jni HelloWorld在当前文件夹中会生成HelloWorld.h。打开HelloWorld.h将会发现如下代码:

/* DO NOT EDIT THIS FILE - it is machine generated */
 #include <jni.h>
 /* Header for class HelloWorld */
 #ifndef _Included_HelloWorld
 #define _Included_HelloWorld
 #ifdef __cplusplus
 extern "C" {
 #endif
 /*
  * Class:     HelloWorld
  * Method:    print
  * Signature: ()V
  */
 JNIEXPORT void JNICALL Java_HelloWorld_print
   (JNIEnv *, jobject);#ifdef __cplusplus
 }
 #endif


#endif该文件中包含了一个函数Java_HelloWorld_print的声明。这里面包含两个参数,非常重要,后面讲实现的时候会讲到。
实现HelloWorld.c
创建HelloWorld.c文件输入如下的代码:

#include <jni.h>
 #include <stdio.h>
 #include "HelloWorld.h"
 JNIEXPORT void JNICALL 
     Java_HelloWorld_print(JNIEnv *env, jobject obj)
 {
  printf("Hello World!\n");
 }


注意必须要包含jni.h头文件,该文件中定义了JNI用到的各种类型,宏定义等。
另外需要注意Java_HelloWorld_print的两个参数,本例比较简单,不需要用到这两个参数。但是这两个参数在JNI中非常重要。
env代表java虚拟机环境,Java传过来的参数和c有很大的不同,需要调用JVM提供的接口来转换成C类型的,就是通过调用env方
法来完成转换的。
obj代表调用的对象,相当于c++的this。当c函数需要改变调用对象成员变量时,可以通过操作这个对象来完成。
编译生成libHelloWorld.so
在Linux下执行如下命令来完成编译工作:

cc -I/usr/lib/jvm/java-6-sun/include/linux/
    -I/usr/lib/jvm/java-6-sun/include/
     -fPIC -shared -o libHelloWorld.so HelloWorld.c在当前目录生成libHelloWorld.so。注意一定需要包含Java的include


    目录(请根据自己系统环境设定),因为Helloworld.c中包含了jni.h。
另外一个值得注意的是在HelloWorld.java中我们LoadLibrary方法加载的是“HelloWorld”,可我们生成的Library却是libHelloWorld。
这是Linux的链接规定的,一个库的必须要是:lib+库名+.so。链接的时候只需要提供库名就可以了。
运行Java程序HelloWorld
大功告成最后一步,验证前面的成果的时刻到了:
java HelloWorld如果你这步发生问题,如果这步你收到java.lang.UnsatisfiedLinkError异常,可以通过如下方式指明共享库的路径:

java -Djava.library.path='.' HelloWorld

问题1:java中没有实现这种“byte a = 0xB2 --> String b = “B2””转换的简单实现需要自己实现。
答:自己编写的转换函数,思路将byte的高低4位分开,分别转换为对应的字符然后合成返回的字符串。

public static String byteToString(byte b) {
 byte high, low;
 byte maskHigh = (byte)0xf0;
 byte maskLow = 0x0f;
 high = (byte)((b & maskHigh) >> 4);
 low = (byte)(b & maskLow);
 StringBuffer buf = new StringBuffer();
 buf.append(findHex(high));
 buf.append(findHex(low));
 return buf.toString();
 }
 private static char findHex(byte b) {
 int t = new Byte(b).intValue();
 t = t < 0 ? t + 16 : t;
 if ((0 <= t) &&(t <= 9)) {
 return (char)(t + '0');
 }
 return (char)(t-10+'A');
 }


未解决的疑问在java中不存在类似C中的无符号量,所以如果一个字节超过0x80其对应的整型值即为负值,但在高位右移4位后还是负值,
且与对应的正值相差16,比如0xB2经过右移后的期望值是0x0B(11)但实际值是-5与预期的值相差16(这个16通过多次试验得出),对此现象为找到合理的解释。
问题2:“String a=”B2” --> byte b=0xB2”字符的byte转换为byte数据类型
答:思路通过Integer作为转换的中间桥梁

public static int stringToByte(String in, byte[] b) throws Exception {
 if (b.length < in.length() / 2) {
 throw new Exception("byte array too small");
 }
 int j=0;
 StringBuffer buf = new StringBuffer(2);
 for (int i=0; i<in.length(); i++, j++) {
 buf.insert(0, in.charAt(i));
 buf.insert(1, in.charAt(i+1));
 int t = Integer.parseInt(buf.toString(),16);
 System.out.println("byte hex value:" + t);
 b[j] = (byte)t;
 i++;
 buf.delete(0,2);
 }
 return j;
 }


问题3:整数(表示范围限定为两个字节unsigned short)通过Integer.byteValue()转换成byte[2],如果超出一个byte的表示范围将会截断高位的值。
答:思路一个byte能表示的最大整数为256(超过128为负值,超过256将被截断),所以取256的倍数为byte[0],256的余数为byte[1]。

byte[] d = new byte[l+2];
 ….
 buff.put(new Integer(l/256).byteValue());
 buff.put(new Integer(l%256).byteValue());
 自己代码:
 package test;
 import java.io.Serializable;
 import java.util.HashMap;
 import java.util.Map;
 import org.apache.commons.lang.SerializationUtils;
 public class SerialTest {
  public static void main(String... strings) {
   // 将map序列化
   // 唯一方法,调用方法
   Map mp = new HashMap();
   mp.put("1", new SeriaTestClass());
   mp.put("2", "cde");
   byte[] mpbytes = SerializationUtils.serialize((Serializable) mp);
   StringBuilder sb = new StringBuilder();
   for (byte b : mpbytes) {
    sb.append(byteToString(b));
   }
   String bytestr = sb.toString();
   System.out.println(bytestr);
   // 将bytestr反序列化
   // 方法1,直接些
   int dtbyteslen = bytestr.length();
   byte[] dtbytes = new byte[dtbyteslen / 2];
   for (int i = 0; i < dtbyteslen; i += 2) {
    String scut = bytestr.substring(i, i + 2);
    int tempi = Integer.valueOf(scut, 16);
    dtbytes[i / 2] = (byte) tempi;
   }
   Object o1 = SerializationUtils.deserialize(dtbytes);
   System.out.println(o1);
   // 方法2,调用方法
   byte[] bts = HexString2Bytes(bytestr);
   Object o2 = SerializationUtils.deserialize(bts);
   System.out.println(o2);
   System.out.println(o1 == o2);
   System.out.println(o1.equals(o2));
  } 
  private static byte uniteBytes(byte src0, byte src1) {
   byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))
     .byteValue();
   _b0 = (byte) (_b0 << 4);
   byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))
     .byteValue();
   byte ret = (byte) (_b0 ^ _b1);
   return ret;
  }
  private static byte[] HexString2Bytes(String src) {
   int len = src.length();
   byte[] ret = new byte[len / 2];
   byte[] tmp = src.getBytes();
   for (int i = 0; i < len; i += 2) {
    ret[i / 2] = uniteBytes(tmp[i], tmp[i + 1]);
   }
   return ret;
  }
  public static String byteToString(byte b) {
   byte high, low;
   byte maskHigh = (byte) 0xf0;
   byte maskLow = 0x0f;
   high = (byte) ((b & maskHigh) >> 4);
   low = (byte) (b & maskLow);
   StringBuffer buf = new StringBuffer();
   buf.append(findHex(high));
   buf.append(findHex(low));
   return buf.toString();
  }
  private static char findHex(byte b) {
   int t = new Byte(b).intValue();
   t = t < 0 ? t + 16 : t;
   if ((0 <= t) && (t <= 9)) {
    return (char) (t + '0');
   }
   return (char) (t - 10 + 'A');
  }

三、string和byte[]
string其实核心是char[],然而要把byte转化成string,必须经过编码。string.length()其实就是char数组的长度,如果使用不同的编码,很可能会错分,造成散字和乱码。例如:

String encoding = “”; 
 byte [] b={(byte)'\u00c4',(byte)'\u00e3'}; 
 String str=new String(b,encoding);


如果encoding=8859_1,会有两个字,但是encoding=gb2312只有一个字这个问题在处理分页是经常发生。
四、Reader,Writer / InputStream,OutputStream
Reader和Writer核心是char,InputStream和OutputStream核心是byte。但是Reader和Writer的主要目的是要把char读/写InputStream/OutputStream。例如:
文件test.txt只有一个"你"字,0xc4,0xe3

String encoding = "gb2312"; 
 InputStreamReader reader = new InputStreamReader(new FileInputStream( 
 "text.txt"), encoding); 
 char c[] = new char[10]; 
 int length = reader.read(c); 
 for (int i = 0; i < length; i++) { 
 System.out.println(c[i]); 
 }