自己实现的Java数据序列化与反序列化

概要:

自己实现的Java数据序列化与反序列化

| |目录

序列化与反序列化,

String类型最大字节长度65535,也就是64k,大概能写21000个汉字,

byte[]类型最大字节长度是Integer.Max,理论支持2G大小,

单个数据包长度理论支持2G,请根据你的内存量力而行,

package com.itshidu.io;

import java.nio.charset.Charset;
import java.util.Arrays;

import com.itshidu.util.BitConverter;

/**
 * 发送的请求数据
 * 数据类型:String_255=0;String_65535=1;Int8=2;Int16=3;Int32=4;Int64=5;Float=6;Double=7;Boolean=8;Char=9;Byte[]=10;
 * String类型数值最大65535字节(UTF8字符集,每个汉字3字节)
 * @author Master.Xia
 */
public class NetMessage{
	
	public static byte[] Concat(byte[]... bs) {
		int len = 0,idx=0;
		for(byte[] b:bs)len+=b.length;
		byte[] buffer = new byte[len];
		for(byte[] b:bs) {
			System.arraycopy(b,0, buffer, idx, b.length);
			idx+=b.length;
		}
		return buffer;
	}
	
	public int code;	//0-255
	public int subCode;	//0-255
	public Object[] data;
	public byte[] GetBytes() {
		byte[] buffer = new byte[]{(byte)(code-128),(byte)(subCode-128)};
		buffer = Concat(buffer,new byte[] {(byte)data.length});
		for(int i=0;i<data.length;i++) {
			if(data[i] instanceof String) {			//String
				byte[] typeBytes = null;
				byte[] lenBytes = null;
				byte[] strBytes=((String)data[i]).getBytes(Charset.forName("UTF-8"));
				if(strBytes.length<=255) {
					typeBytes = new byte[]{(byte)0};
					lenBytes=new byte[]{(byte)(strBytes.length-128)};
				}else if(strBytes.length<=65535) {
					typeBytes = new byte[]{(byte)1};
					lenBytes=BitConverter.GetBytes((short)(strBytes.length-32768));
				}else {
					throw new RuntimeException("String Byte Length Out of Bounds:"+strBytes.length);
				}
				buffer = Concat(buffer,typeBytes,lenBytes,strBytes);
			}else if(data[i] instanceof Byte) {		//Int8
				byte[] typeBytes = new byte[]{(byte)2};
				byte[] dataBytes = new byte[]{(byte)data[i]};
				buffer = Concat(buffer,typeBytes,dataBytes);
			}else if(data[i] instanceof Short) {	//Int16
				byte[] typeBytes = new byte[]{(byte)3};
				byte[] dataBytes=BitConverter.GetBytes((short)data[i]);
				buffer = Concat(buffer,typeBytes,dataBytes);
			}else if(data[i] instanceof Integer) {	//Int32
				byte[] typeBytes = new byte[]{(byte)4};
				byte[] dataBytes=BitConverter.GetBytes((int)data[i]);
				buffer = Concat(buffer,typeBytes,dataBytes);
			}else if(data[i] instanceof Long) {		//Int64
				byte[] typeBytes = new byte[]{(byte)5};
				byte[] dataBytes=BitConverter.GetBytes((long)data[i]);
				buffer = Concat(buffer,typeBytes,dataBytes);
			}else if(data[i] instanceof Float) {	//Float
				byte[] typeBytes = new byte[]{(byte)6};
				byte[] dataBytes = BitConverter.GetBytes((float)data[i]);
				buffer = Concat(buffer,typeBytes,dataBytes);
			}else if(data[i] instanceof Double) {	//Double
				byte[] typeBytes = new byte[]{(byte)7};
				byte[] dataBytes = BitConverter.GetBytes(Double.doubleToLongBits((double)data[i]));
				buffer = Concat(buffer,typeBytes,dataBytes);
			}else if(data[i] instanceof Boolean) {	//Boolean
				byte[] typeBytes = new byte[]{(byte)8};
				byte[] dataBytes = new byte[]{(byte)(((boolean)data[i])? 1:0)};
				buffer = Concat(buffer,typeBytes,dataBytes);
			}else if(data[i] instanceof Character) {//Char
				byte[] typeBytes = new byte[]{(byte)9};
				byte[] dataBytes = new String(new char[] {(char)data[i]}).getBytes(Charset.forName("UTF-8"));
	            byte[] lenBytes = new byte[] { (byte)dataBytes.length };
				buffer = Concat(buffer,typeBytes,lenBytes,dataBytes);
			}else if(data[i] instanceof byte[]||data[i] instanceof Byte[]) {	//byte[]:|Type:1byte|DataLen:4byte|Data|
				byte[] typeBytes = new byte[]{(byte)10};
				byte[] dataBytes = null;
				if(data[i] instanceof Byte[]){
					Byte[] bs1 = (Byte[])data[i];
					dataBytes = new byte[bs1.length];
					for(int m=0;m<bs1.length;m++){
						dataBytes[m]=(byte)bs1[m];
					}
				}else {
					dataBytes = (byte[])data[i];
				}
				byte[] lenBytes=BitConverter.GetBytes(dataBytes.length);
				buffer = Concat(buffer,typeBytes,lenBytes,dataBytes);
			}
		}
		return buffer;
	}
	public NetMessage(byte[] bytes){
		this.code = bytes[0]+128;
		this.subCode = bytes[1]+128;
		int count = BitConverter.ByteToInt(bytes[2]);
		int index = 3;
		this.data = new Object[count];
		for(int i=0;i<count;i++) {
			int argType = BitConverter.ByteToInt(bytes[index++]);
			if(argType==0) { //String_255
				int len = BitConverter.ByteToInt((byte)(128+bytes[index++]));
				data[i] = new String(bytes,index,len,Charset.forName("UTF-8"));
				index += len;
			}else if(argType==1) { //String_65535
				int len = BitConverter.ToInt16(bytes, index)+32768;
				index += 2;
				data[i] = new String(bytes,index,len,Charset.forName("UTF-8"));
				index += len;
			}else if(argType==2) { //Byte
				data[i] = BitConverter.ByteToInt(bytes[index++]);
			}else if(argType==3) { //Short
				data[i] = BitConverter.ToInt16(bytes, index);
				index += 2;
			}else if(argType==4) { //Int
				data[i] = BitConverter.ToInt32(bytes, index);
				index += 4;
			}else if(argType==5) { //Long
				data[i] = BitConverter.ToInt64(bytes, index);
				index += 8;
			}else if(argType==6) { //Float
				data[i] = BitConverter.ToFloat(bytes, index);
				index += 4;
			}else if(argType==7) { //Double
				data[i] = Double.longBitsToDouble(BitConverter.ToInt64(bytes, index));
				index+=8;
			}else if(argType==8) { //Boolean
				data[i]=(bytes[index++]==0x00)? false:true;
			}else if(argType==9) { //Char
				Charset charset = Charset.forName("UTF-8");
				int len = BitConverter.ByteToInt(bytes[index++]);
				data[i] = new String(bytes,index,len,charset).toCharArray()[0];
				index += len;
			}else if(argType==10) { //Byte[]
				int len6 = BitConverter.ToInt32(bytes, index);
				index += 4;
				data[i] = new byte[len6];
				System.arraycopy(bytes, index, data[i], 0, len6);
				index += len6;
			}else {
				System.out.println("无法识别的类型码:"+argType);
			}
			
		}
	}
	public byte[] pack() {
		byte[] dataBytes = this.GetBytes();
		byte[] lenBytes = BitConverter.GetBytes(dataBytes.length);
		return Concat(lenBytes,dataBytes);
	}
	public NetMessage(byte[] bytes,int offset,int length) {
		this(Arrays.copyOfRange(bytes, offset, offset+length));
	}

	public NetMessage(int reqCode,int subCode,Object...objects) {
		this.code = reqCode;
		this.subCode = subCode;
		this.data = objects;
	}
	public NetMessage(int reqCode,int subCode) {
		this.code = reqCode;
		this.subCode = subCode;
	}
	public NetMessage(int reqCode) {
		this.code = reqCode;
	}
	
	
	public static void main(String[] args) {
		NetMessage a = new NetMessage(
				(byte)0,(byte)200,(byte)100,(short)1000,(int)10000,(long)100000,1.414f,3.141592654,true,false,'@','哈'
				,"HelloWorld".getBytes()
				,"中华人民共和国万岁".getBytes()
				,123
				);
		
		byte[] bs = a.GetBytes();
		
		NetMessage b = new NetMessage(bs);
		System.out.println("ReqCode:"+b.code);
		System.out.println("SubCode:"+b.subCode);
		for(Object o : b.data) {
			System.out.println(o);
		}
		System.out.println(new String((byte[])b.data[b.data.length-2]));
		
	}
	
	
}


网络传输的基础就是字节,所以无论什么语言,只要按照此处的规则进行对应,都可以相互转化。

评论关闭
评论 还能输入200
评论关闭
评论 还能输入200
资料加载中...
已关注 , 取消