在Java的网络编程中传输的经常是byte数组,但我们实际中使用的数据类型可能是任一种数据类型,这就需要在它们之间相互转换,转换的核心在于将其他类型的数据的每一位转换成byte类型的数据。
下面给出相关的转换代码——
1.short与byte数组的互转
/**
* 转换short为byte
*
* @param b
* @param s 需要转换的short
* @param index
*/
public static void putShort(byte b[], short s, int index) {
b[index + 1] = (byte) (s >> 8);
b[index + 0] = (byte) (s >> 0);
}
/**
* 通过byte数组取到short
*
* @param b
* @param index 第几位开始取
* @return
*/
public static short getShort(byte[] b, int index) {
return (short) (((b[index + 1] << 8) | b[index + 0] & 0xff));
}
2.int与byte数组的互转
/**
*将32位的int值放到4字节的byte数组
* @param num
* @return
*/
public static byte[] intToByteArray(int num) {
byte[] result = new byte[4];
result[0] = (byte)(num >>> 24);//取最高8位放到0下标
result[1] = (byte)(num >>> 16);//取次高8为放到1下标
result[2] = (byte)(num >>> 8); //取次低8位放到2下标
result[3] = (byte)(num ); //取最低8位放到3下标
return result;
}
/**
* 将4字节的byte数组转成一个int值
* @param b
* @return
*/
public static int byteArrayToInt(byte[] b){
byte[] a = new byte[4];
int i = a.length - 1,j = b.length - 1;
for (; i >= 0 ; i--,j--) {//从b的尾部(即int值的低位)开始copy数据
if(j >= 0)
a[i] = b[j];
else
a[i] = 0;//如果b.length不足4,则将高位补0
}
int v0 = (a[0] & 0xff) << 24;//&0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
int v1 = (a[1] & 0xff) << 16;
int v2 = (a[2] & 0xff) << 8;
int v3 = (a[3] & 0xff) ;
return v0 + v1 + v2 + v3;
}
3.long与byte数组的互转
/**
* 将64位的long值放到8字节的byte数组
* @param num
* @return 返回转换后的byte数组
*/
public static byte[] longToByteArray(long num) {
byte[] result = new byte[8];
result[0] = (byte) (num >>> 56);// 取最高8位放到0下标
result[1] = (byte) (num >>> 48);// 取最高8位放到0下标
result[2] = (byte) (num >>> 40);// 取最高8位放到0下标
result[3] = (byte) (num >>> 32);// 取最高8位放到0下标
result[4] = (byte) (num >>> 24);// 取最高8位放到0下标
result[5] = (byte) (num >>> 16);// 取次高8为放到1下标
result[6] = (byte) (num >>> 8); // 取次低8位放到2下标
result[7] = (byte) (num); // 取最低8位放到3下标
return result;
}
/**
* 将8字节的byte数组转成一个long值
* @param byteArray
* @return 转换后的long型数值
*/
public static long byteArrayToInt(byte[] byteArray) {
byte[] a = new byte[8];
int i = a.length - 1, j = byteArray.length - 1;
for (; i >= 0; i--, j--) {// 从b的尾部(即int值的低位)开始copy数据
if (j >= 0)
a[i] = byteArray[j];
else
a[i] = 0;// 如果b.length不足4,则将高位补0
}
// 注意此处和byte数组转换成int的区别在于,下面的转换中要将先将数组中的元素转换成long型再做移位操作,
// 若直接做位移操作将得不到正确结果,因为Java默认操作数字时,若不加声明会将数字作为int型来对待,此处必须注意。
long v0 = (long) (a[0] & 0xff) << 56;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
long v1 = (long) (a[1] & 0xff) << 48;
long v2 = (long) (a[2] & 0xff) << 40;
long v3 = (long) (a[3] & 0xff) << 32;
long v4 = (long) (a[4] & 0xff) << 24;
long v5 = (long) (a[5] & 0xff) << 16;
long v6 = (long) (a[6] & 0xff) << 8;
long v7 = (long) (a[7] & 0xff);
return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7;
}
4.float与byte数组的互转
/**
* float转换byte
*
* @param bb
* @param x
* @param index
*/
public static void putFloat(byte[] bb, float x, int index) {
// byte[] b = new byte[4];
int l = Float.floatToIntBits(x);
for (int i = 0; i < 4; i++) {
bb[index + i] = new Integer(l).byteValue();
l = l >> 8;
}
}
/**
* 通过byte数组取得float
*
* @param bb
* @param index
* @return
*/
public static float getFloat(byte[] b, int index) {
int l;
l = b[index + 0];
l &= 0xff;
l |= ((long) b[index + 1] << 8);
l &= 0xffff;
l |= ((long) b[index + 2] << 16);
l &= 0xffffff;
l |= ((long) b[index + 3] << 24);
return Float.intBitsToFloat(l);
}
5.double与byte数组的互转
/**
* double转换byte
*
* @param bb
* @param x
* @param index
*/
public static void putDouble(byte[] bb, double x, int index) {
// byte[] b = new byte[8];
long l = Double.doubleToLongBits(x);
for (int i = 0; i < 4; i++) {
bb[index + i] = new Long(l).byteValue();
l = l >> 8;
}
}
/**
* 通过byte数组取得float
*
* @param bb
* @param index
* @return
*/
public static double getDouble(byte[] b, int index) {
long l;
l = b[0];
l &= 0xff;
l |= ((long) b[1] << 8);
l &= 0xffff;
l |= ((long) b[2] << 16);
l &= 0xffffff;
l |= ((long) b[3] << 24);
l &= 0xffffffffl;
l |= ((long) b[4] << 32);
l &= 0xffffffffffl;
l |= ((long) b[5] << 40);
l &= 0xffffffffffffl;
l |= ((long) b[6] << 48);
l &= 0xffffffffffffffl;
l |= ((long) b[7] << 56);
return Double.longBitsToDouble(l);
}
6、字符串和十六进制数的互转
写了一个工具类供大家参考:
package com.csc.stringtobyte;
public class StringToByte{
public static void main(String[] args) {
String string = new String("hello world!");
byte[] stringByte = string.getBytes();
String hexString = bytesToHexString(stringByte);
System.out.println(hexString);
byte[] binByte = hexStringToBytes(hexString);
String result = new String(binByte);
System.out.println(result);
}
/**
* Convert byte[] to hex string.这里我们可以将byte转换成int,然后利用Integer.toHexString(int)来转换成16进制字符串。
* @param src byte[] data
* @return hex string
*/
public static String bytesToHexString(byte[] src){
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* Convert hex string to byte[]
* @param hexString the hex string
* @return byte[]
*/
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
/**
* Convert char to byte
* @param c char
* @return byte
*/
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
}
7、将对象系列化成十六进制的字符串以及将十六机制的字符串反序列化成对象
写了一个工具类供大家参考:
package com.csc.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Locale;
public class SerializeTool {
/**
* 将传入的对象系列化后,存入参数string指定的文件,并将序列化后的对象转换成十六进制字符串返回
* @param object 可序列化的对象
* @param string 存储文件名
* @return string 序列化后的对象的十六进制字符串
* @throws FileNotFoundException
* @throws IOException
*/
public static String writeObject(Object object, String strFile)
throws FileNotFoundException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//用于将对象转换成byte[]数组的ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(baos);
//将对象写入ByteArrayOutputStream
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
//用于将将对象存入文件的ObjectOutputStream
ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(
strFile));
//将对象写入string指定的文件中
oos2.writeObject(object);
oos.close();
oos2.close();
baos.close();
return bytesToHexString(bytes);
}
/**
* 将序列化后且用十六进制字符表示的对象反序列化成对象
* @param hexString 序列化对象的十六进制表示形式的字符串
* @return 反序列化生成的对象
* @throws IOException
* @throws ClassNotFoundException
*/
public static Object readObject(String hexString) throws IOException,
ClassNotFoundException {
byte[] bytes = hexStringToBytes(hexString);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
/**
* 将传入的byte[]数组转换成十六机制数的字符串
* @param src 要转换的byte数组
* @return 返回十六进制的字符串
*/
private static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
//将一个byte的二进制数转换成十六进制字符
String hv = Integer.toHexString(v);
//如果二进制数转换成十六进制数高位为0,则加入'0'字符
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* 将传进来的十六进制表示的字符串转换成byte数组
* @param hexString
* @return 二进制表示的byte[]数组
*/
private static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase(Locale.getDefault());
int length = hexString.length() / 2;
//将十六进制字符串转换成字符数组
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
//一次去两个字符
int pos = i * 2;
//两个字符一个对应byte的高四位一个对应第四位
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
/**
* 将传进来的字符代表的数字转换成二进制数
* @param c 要转换的字符
* @return 以byte的数据类型返回字符代表的数字的二进制表示形式
*/
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
}
