为您推荐:
精华内容
最热下载
问答
  • 5星
    14KB weixin_42696271 2021-09-11 03:41:54
  • 5星
    1KB weixin_42696271 2021-09-10 20:45:53
  • 5星
    17KB younow22 2021-02-15 20:33:07
  • 5星
    43KB qq_34093397 2021-01-04 10:45:38
  • 5星
    1.61MB m0_54656292 2021-08-26 23:28:23
  • 5星
    10KB weixin_42696333 2021-09-10 22:42:23
  • 5星
    145.04MB qq_31988139 2021-08-10 09:54:59
  • 5星
    2.44MB Johnho130 2021-07-13 20:48:23
  • 5星
    1.56MB m0_52957036 2020-10-30 02:50:05
  • 5星
    11.8MB guoruibin123 2021-05-21 15:45:32
  • 字节序列:序列化 字节序列–>对象 :反序列化 序列化的用途:把对象的字节序列保存在磁盘上,通常存放在一个文件中;在网络上传送对象的字节序列。 存储在物理磁盘上的:Web服务器中的Session对象。当有 10万...

    对象–>字节序列:序列化
    字节序列–>对象 :反序列化

    序列化的用途:把对象的字节序列保存在磁盘上,通常存放在一个文件中;在网络上传送对象的字节序列。

    1. 存储在物理磁盘上的:Web服务器中的Session对象。当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
    2. 网络传输:当两个进程进行远程通信的时候,彼此可以发送各种类型的数据,无论何种类型的数据都以二进制序列的形式在网络上传送。所以发送方需要将对象序列化,接收方需要将二进制字节序列反序列化成为一个java对象。

    序列化的几种方式

    1.实现Serializable接口

    2.实现Externalizable接口

    Externalizable接口继承自Serializable接口。
    实现Externalizable接口的类完全由自身控制序列化的行为,而仅仅实现Serializable接口的类可以采用默认的序列化的方式。

    Externalizable接口继承了java的序列化接口的基础上,增加了两个方法:

    void writeExternal(ObjectOutput out) throws IOException;
    void readExternal(ObjectInput in) throws IOException,ClassNotFoundException.
    

    我们在序列化对象的时候,由于这个类实现了Externalizable接口,在writeExternal()方法中定义了哪些属性可以序列化,哪些不可以被序列化。
    在反序列化的时候自动调用readExternal()方法,根据序列顺序挨个读取进行反序列化,并自动封装成对象返回,然后在测试类接收,完成了反序列化。

    java中的序列化API

    java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
    java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
      
    对象序列化的步骤:

    1. 创建一个对象输出流(ObjectOutputStream),他可以包装一个其他类型的目标输入流,如文件输出流。
    2. 通过对象输出流的writeObject()方法写对象。

    对象反序列化的步骤:
    3. 创建一个对象输入流(ObjectInputStream),他可以包装一个其他类型的源输入流,如文件输入流。
    4. 通过对象输入流的readObject()方法读取对象。

    代码例子:

    Person类实现Serializable接口
    import java.io.Serializable;
    
    /**
     * <p>ClassName: Person<p>
     * <p>Description:测试对象序列化和反序列化<p>
     * @version 1.0 V
     */
    public class Person implements Serializable {
    
        /**
         * 序列化ID
         */
        private static final long serialVersionUID = -5809782578272943999L;
        private int age;
        private String name;
        private String sex;
    
        public int getAge() {
            return age;
        }
    
        public String getName() {
            return name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    }
    
    序列化和反序列化Person类对象
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.text.MessageFormat;
    
    /**
     * <p>ClassName: TestObjSerializeAndDeserialize<p>
     * <p>Description: 测试对象的序列化和反序列<p>
     */
    public class TestObjSerializeAndDeserialize {
    
        public static void main(String[] args) throws Exception {
            SerializePerson();//序列化Person对象
            Person p = DeserializePerson();//反序列Perons对象
            System.out.println(MessageFormat.format("name={0},age={1},sex={2}",
                                                     p.getName(), p.getAge(), p.getSex()));
        }
        
        /**
         * MethodName: SerializePerson 
         * Description: 序列化Person对象
         * @throws FileNotFoundException
         * @throws IOException
         */
        private static void SerializePerson() throws FileNotFoundException,
                IOException {
            Person person = new Person();
            person.setName("gacl");
            person.setAge(25);
            person.setSex("男");
            // ObjectOutputStream 对象输出流,将Person对象存储到E盘的Person.txt文件中,完成对Person对象的序列化操作
            ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
                    new File("E:/Person.txt")));
            oo.writeObject(person);
            System.out.println("Person对象序列化成功!");
            oo.close();
        }
    
        /**
         * MethodName: DeserializePerson 
         * Description: 反序列Perons对象
         * @return
         * @throws Exception
         * @throws IOException
         */
        private static Person DeserializePerson() throws Exception, IOException {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                    new File("E:/Person.txt")));
            Person person = (Person) ois.readObject();
            System.out.println("Person对象反序列化成功!");
            return person;
        }
    
    }
    

    序列化Person成功后在E盘生成了一个Person.txt文件,而反序列化Person是读取E盘的Person.txt后生成了一个Person对象

    serialVersionUID的作用

    s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D​:​ ​字​面​意​思​上​是​序​列​化​的​版​本​号​,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量

    private static final long serialVersionUID
    

    如果没有明确指定serialVersionUID,序列化的时候会根据字段和特定的算法生成一个serialVersionUID,当属性有变化时这个id发生了变化,所以反序列化的时候就会失败。抛出“本地classd的唯一id和流中class的唯一id不匹配”。

    jdk文档:

    计算默认的 serialVersionUID
    对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的InvalidClassException。因此,为保证 serialVersionUID 值跨不同 java编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private 修饰符显示声明 serialVersionUID(如果可能),原因是这种声明仅应用于直接声明类 – serialVersionUID 字段作为继承成员没有用处。数组类不能声明一个明确的 serialVersionUID,因此它们总是具有默认的计算值,但是数组类没有匹配serialVersionUID 值的要求。
    在这里插入图片描述

    注意事项

    1. 注意不想被序列化的属性需要用transient关键字进行修饰。
    2. 如果先序列化对象A然后序列化对象B,那么反序列化的时候一定要记得java规定先读到的对象是先被序列化的对象。不能先接收对象B,否则会报错;
    3. serialVersionUID:实现序列化接口的对象不强制声明唯一的serialVersionUID,但是该字段对于对象的序列化的兼容性有很大的影响。详解见上。

    其他序列化的几种方式:

    1. 把对象包装成JSON字符串传输: 这里采用JSON格式同时使用采用Google的gson-2.2.2.jar 进行转义
    2. 采用谷歌的ProtoBuf: 随着Google工具protoBuf的开源,protobuf也是个不错的选择。对JSON,Object Serialize(Java的序列化和反序列化),
      资料:
      https://www.cnblogs.com/xdp-gacl/p/3777987.html
      http://www.cnblogs.com/zhengshao/p/8882613.html
    展开全文
    mulinsen77 2019-04-16 17:19:04
  • 一、背景 有项目需要传输Map结构的数据,有人倾向用Java序列化来做,有人倾向用JSON的序列...大家可能对Java序列化都有一个错误的认识,认为Java序列化比JSON的序列化效率高并且序列化的数据小,其实实际上并不一定

    一、背景

    有项目需要传输Map结构的数据,有人倾向用Java序列化来做,有人倾向用JSON的序列化来做。所以我们还是比比吧。

    Java观点:Object2Object,使用时简单快速。

    JSON观点:JSON格式与语言无关,扩展性强,速度也应该不慢。

    大家可能对Java序列化都有一个错误的认识,认为Java序列化比JSON的序列化效率高并且序列化的数据小,其实实际上并不一定是这样,我这次就想通过实际测试来解开这个谜团

    二、测试方式

    测试同一个Map<String,Object>并序列化为byte[],并再将byte[]反序列化为Map<String,Object>的过程。Object中包括String,Integer,Long,Boolean,Float,Double常规类型的数据。

    序列化:Map<String,Object> -> byte[]

    反序列化:byte[] -> Map<String,Object>

    测试各种大小不同的Map,并循环执行同一操作N次,来得到一个相对稳定的线性结果。

    三、比较的对象

    JAVA:

    手写Java(1.6.0_32)与Common Lang3(3.1)的SerializationUtils。

    JSON:

    将采用Gson(2.2.2)与json-smart(2.0-RC2)两种不同的JSON解析器。json-smart号称是速度最快的JSON解析器。

    、比较结果

    Map大小(10-100)循环10万次

    序列化时间比较(y为序列化时间ms)

    反序列化时间比较(y为反序列化时间ms)


    序列化时间汇总比较(y为序列化与反序列化总时间ms)

    序列化后byte大小比较(由于同类线重合显示为2条线)

    Map大小(100-1000)循环1万次

    序列化时间比较(y为序列化时间ms)

    反序列化时间比较(y为反序列化时间ms)

    序列化时间汇总比较(y为序列化与反序列化总时间ms)

    序列化后byte大小比较(由于同类线重合显示为2条线)

    比较总结

    Map在小于100时:
    Java的反序列化时的性能要比Java序列化时性能差很多,1.5倍左右差距。
    JSON序列化性能明显由于Java序列化性能,尤其是反序列化过程。并且序列化后的数据大小也是JSON格式的小。

    Map在大于100小于1000时:
    Java的反序列化时的性能并没有随Map的大小变化而变差。
    JSON阵营中Gson在序列化过程中,比Java只快了那么一点点。在反序列化过程中Gson开始领先与Java,但在Map的大小过700多以后,Gson的反序列化性能
    比Java要慢。但JSON阵营中的json-smart依然表现出色完全是两个级别。

    并不是Java的序列化速度总是最快体积最小,Java需要考虑对象类型,属性类型与内部对象信息等一系列对数据本身并不相关的内容的处理。JSON以固定的格式,稳定简单的数据结构大大简化了序列化过程,虽然也要创建新的Java数据对象但并不会比Java反序列化的速度慢。

    从测试结果上看JSON的json-smart更适合项目的需要。

    五、测试代码源码

    SerializationTest接口

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package org.noahx.javavsjson;
     
    import java.util.Map;
     
    /**
      * Created with IntelliJ IDEA.
      * User: noah
      * Date: 3/8/13
      * Time: 9:59 PM
      * To change this template use File | Settings | File Templates.
      */
    public interface SerializationTest {
     
         public String getTestName();
     
         public Map<String, Object> testBytes2Map( byte [] bytes);
     
         public byte [] testMap2Bytes(Map<String, Object> map);
    }


    JavaSerializationTest

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    package org.noahx.javavsjson;
     
    import java.io.*;
    import java.util.Map;
     
    /**
      * Created with IntelliJ IDEA.
      * User: noah
      * Date: 3/8/13
      * Time: 10:05 PM
      * To change this template use File | Settings | File Templates.
      */
    public class JavaSerializationTest implements SerializationTest {
     
         @Override
         public String getTestName() {
             return "Java" ;
         }
     
         @Override
         public Map<String, Object> testBytes2Map( byte [] bytes) {
             Map<String, Object> result = null ;
             try {
                 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
                 ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
     
                 result = (Map<String, Object>) inputStream.readObject();
                 inputStream.close();
             } catch (ClassNotFoundException e) {
                 e.printStackTrace();
             } catch (IOException e) {
                 e.printStackTrace();
             }
     
             return result;
         }
     
         @Override
         public byte [] testMap2Bytes(Map<String, Object> map) {
             byte [] bytes = null ;
             try {
                 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                 ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
     
                 outputStream.writeObject(map);
                 outputStream.close();
     
                 bytes = byteArrayOutputStream.toByteArray();
             } catch (IOException e) {
                 e.printStackTrace();
             }
             return bytes;
         }
    }


    CommonLang3SerializationTest

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    package org.noahx.javavsjson;
     
    import org.apache.commons.lang3.SerializationUtils;
     
    import java.io.Serializable;
    import java.util.Map;
     
    /**
      * Created with IntelliJ IDEA.
      * User: noah
      * Date: 3/9/13
      * Time: 2:24 AM
      * To change this template use File | Settings | File Templates.
      */
    public class CommonLang3SerializationTest implements SerializationTest {
         @Override
         public String getTestName() {
             return "Commons Lang3" ;
         }
     
         @Override
         public Map<String, Object> testBytes2Map( byte [] bytes) {
             return (Map<String, Object>) SerializationUtils.deserialize(bytes);
         }
     
         @Override
         public byte [] testMap2Bytes(Map<String, Object> map) {
             return SerializationUtils.serialize((Serializable) map);
         }
    }


    GsonSerializationTest

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    package org.noahx.javavsjson;
     
    import com.google.gson.Gson;
     
    import java.io.UnsupportedEncodingException;
    import java.util.Map;
     
    /**
      * Created with IntelliJ IDEA.
      * User: noah
      * Date: 3/8/13
      * Time: 10:02 PM
      * To change this template use File | Settings | File Templates.
      */
    public class GsonSerializationTest implements SerializationTest {
     
         private Gson gson;
     
         public GsonSerializationTest() {
             gson = new Gson();
         }
     
         @Override
         public String getTestName() {
             return "Gson" ;
         }
     
         @Override
         public Map<String, Object> testBytes2Map( byte [] bytes) {
             Map<String, Object> result = null ;
             try {
                 result = gson.fromJson( new String(bytes, "UTF-8" ), Map. class );
             } catch (UnsupportedEncodingException e) {
                 e.printStackTrace();
             }
             return result;
         }
     
         @Override
         public byte [] testMap2Bytes(Map<String, Object> map) {
             String str = gson.toJson(map);
             byte [] bytes = null ;
             try {
                 bytes = str.getBytes( "UTF-8" );
             } catch (UnsupportedEncodingException e) {
                 e.printStackTrace();
             }
             return bytes;
         }
    }


    JsonSmartSerializationTest

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    package org.noahx.javavsjson;
     
    import net.minidev.json.JSONObject;
    import net.minidev.json.JSONValue;
    import net.minidev.json.parser.ParseException;
     
    import java.io.UnsupportedEncodingException;
    import java.util.Map;
     
    /**
      * Created with IntelliJ IDEA.
      * User: noah
      * Date: 3/9/13
      * Time: 1:30 AM
      * To change this template use File | Settings | File Templates.
      */
    public class JsonSmartSerializationTest implements SerializationTest {
         @Override
         public String getTestName() {
             return "Json Smart" ;
         }
     
         @Override
         public Map<String, Object> testBytes2Map( byte [] bytes) {
             Map<String, Object> map = null ;
             try {
                 map = (Map<String, Object>) JSONValue.parseStrict(( new String(bytes, "UTF-8" )));
             } catch (ParseException e) {
                 e.printStackTrace();
             } catch (UnsupportedEncodingException e) {
                 e.printStackTrace();
             }
             return map;
         }
     
         @Override
         public byte [] testMap2Bytes(Map<String, Object> map) {
             String str = JSONObject.toJSONString(map);
             byte [] result = null ;
             try {
                 result = str.getBytes( "UTF-8" );
             } catch (UnsupportedEncodingException e) {
                 e.printStackTrace();
             }
             return result;
         }
    }

    源码下载:http://sdrv.ms/12ECmgG

    P.S.

    我也测试过Map<String,String>固定数据类型value只为String的情况,这时Java与JSON的性能的差距会减小,但JSON序列化性能与数据大小还是占优势,尤其是反序列化的速度JSON更出色。

    Gson在数值反序列化后,因为Object无法确定类型,Map中的Long,Integer,Float统一转为了Double类型。
    json-smart不一样,如果整数超过Integer的范围转Long,没有超过转Integer。浮点Float转为Double类型。

    展开全文
    cws1214 2016-02-23 18:05:30
  • 在项目中需要PHP公用一个MySQL数据库,有些数据需要序列化之后保存,这就需要将待存储的数据序列化之后存到数据库中,取出的时候,需要反序列化之后才能正常使用。 原数据: {&quot;06008816930683722.jpg&...

    在项目中需要和PHP公用一个MySQL数据库,有些数据需要序列化之后保存,这就需要将待存储的数据序列化之后存到数据库中,取出的时候,需要反序列化之后才能正常使用。
    原数据:

    {"06008816930683722.jpg", "06008816930681525.jpg"}
    

    数据库中存的数据是这样的:

    a:1:{s:5:"buyer";a:2:{i:1;s:21:"06008816930683722.jpg";i:2;s:21:"06008816930681525.jpg";}}
    

    首先是借助一个PHP的序列化工具:

    		<dependency>
    			<groupId>org.sction</groupId>
    			<artifactId>phprpc</artifactId>
    			<version>3.0.2</version>
    		</dependency>
    

    PHPSerializer.java

    package com.thinkgem.jeesite.common.utils;
    
    import java.io.*;
    import java.util.*;
    import java.lang.reflect.*;
    
    import org.lorecraft.phparser.SerializedPhpParser;
    
    /**
     * Description:
     * 
     * @author : ss Shi
     * @date :2016-4-12 下午1:27:06
     */
    
    class UnSerializeResult {
        public Object value;
        public int hv;
        public UnSerializeResult() {}
        public UnSerializeResult(Object value, int hv) {
            this.value = value;
            this.hv = hv;
        }
    }
    public class PHPSerializer {
    	private static Package[] __packages = Package.getPackages();
    	private static final byte __Quote = 34;
    	private static final byte __0 = 48;
    	private static final byte __1 = 49;
    	private static final byte __Colon = 58;
    	private static final byte __Semicolon = 59;
    	private static final byte __C = 67;
    	private static final byte __N = 78;
    	private static final byte __O = 79;
    	private static final byte __R = 82;
    	private static final byte __U = 85;
    	private static final byte __Slash = 92;
    	private static final byte __a = 97;
    	private static final byte __b = 98;
    	private static final byte __d = 100;
    	private static final byte __i = 105;
    	private static final byte __r = 114;
    	private static final byte __s = 115;
    	private static final byte __LeftB = 123;
    	private static final byte __RightB = 125;
    	private static final String __NAN = new String("NAN");
    	private static final String __INF = new String("INF");
    	private static final String __NINF = new String("-INF");
    
    	private PHPSerializer() {
    	}
    
    	public static byte[] serialize(Object obj) {
    		return serialize(obj, "UTF-8");
    	}
    
    	public static byte[] serialize(Object obj, String charset) {
    		HashMap ht = new HashMap();
    		int hv = 1;
    		ByteArrayOutputStream stream = new ByteArrayOutputStream();
    
    		hv = serialize(stream, obj, ht, hv, charset);
    		byte[] result = stream.toByteArray();
    
    		try {
    			stream.close();
    		} catch (Exception e) {
    		}
    		return result;
    	}
    
    	public static int serialize(ByteArrayOutputStream stream, Object obj,
    			HashMap ht, int hv, String charset) {
    		if (obj == null) {
    			hv++;
    			writeNull(stream);
    		} else {
    			if (obj instanceof Boolean) {
    				hv++;
    				writeBoolean(stream, ((Boolean) obj).booleanValue() ? __1 : __0);
    			} else if ((obj instanceof Byte) || (obj instanceof Short)
    					|| (obj instanceof Integer)) {
    				hv++;
    				writeInteger(stream, getBytes(obj));
    			} else if (obj instanceof Long) {
    				hv++;
    				writeDouble(stream, getBytes(obj));
    			} else if (obj instanceof Float) {
    				hv++;
    				Float f = (Float) obj;
    
    				if (f.isNaN()) {
    					writeDouble(stream, getBytes(__NAN));
    				} else if (f.isInfinite()) {
    					if (f.floatValue() > 0) {
    						writeDouble(stream, getBytes(__INF));
    					} else {
    						writeDouble(stream, getBytes(__NINF));
    					}
    				} else {
    					writeDouble(stream, getBytes(f));
    				}
    			} else if (obj instanceof Double) {
    				hv++;
    				Double d = (Double) obj;
    
    				if (d.isNaN()) {
    					writeDouble(stream, getBytes(__NAN));
    				} else if (d.isInfinite()) {
    					if (d.doubleValue() > 0) {
    						writeDouble(stream, getBytes(__INF));
    					} else {
    						writeDouble(stream, getBytes(__NINF));
    					}
    				} else {
    					writeDouble(stream, getBytes(d));
    				}
    			} else if ((obj instanceof Character) || (obj instanceof String)) {
    				hv++;
    				writeString(stream, getBytes(obj, charset));
    			} else if (obj.getClass().isArray()) {
    				if (ht.containsKey(new Integer(obj.hashCode()))) {
    					writePointRef(stream,
    							getBytes(ht.get(new Integer(obj.hashCode()))));
    				} else {
    					ht.put(new Integer(obj.hashCode()), new Integer(hv++));
    					hv = writeArray(stream, obj, ht, hv, charset);
    				}
    			} else if (obj instanceof ArrayList) {
    				if (ht.containsKey(new Integer(obj.hashCode()))) {
    					writePointRef(stream,
    							getBytes(ht.get(new Integer(obj.hashCode()))));
    				} else {
    					ht.put(new Integer(obj.hashCode()), new Integer(hv++));
    					hv = writeArrayList(stream, (ArrayList) obj, ht, hv,
    							charset);
    				}
    			} else if (obj instanceof HashMap) {
    				if (ht.containsKey(new Integer(obj.hashCode()))) {
    					writePointRef(stream,
    							getBytes(ht.get(new Integer(obj.hashCode()))));
    				} else {
    					ht.put(new Integer(obj.hashCode()), new Integer(hv++));
    					hv = writeHashMap(stream, (HashMap) obj, ht, hv, charset);
    				}
    			} else {
    				if (ht.containsKey(new Integer(obj.hashCode()))) {
    					hv++;
    					writeRef(stream,
    							getBytes(ht.get(new Integer(obj.hashCode()))));
    				} else {
    					ht.put(new Integer(obj.hashCode()), new Integer(hv++));
    					hv = writeObject(stream, obj, ht, hv, charset);
    				}
    			}
    		}
    		return hv;
    	}
    
    	private static void writeNull(ByteArrayOutputStream stream) {
    		stream.write(__N);
    		stream.write(__Semicolon);
    	}
    
    	private static void writeRef(ByteArrayOutputStream stream, byte[] r) {
    		stream.write(__r);
    		stream.write(__Colon);
    		stream.write(r, 0, r.length);
    		stream.write(__Semicolon);
    	}
    
    	private static void writePointRef(ByteArrayOutputStream stream, byte[] p) {
    		stream.write(__R);
    		stream.write(__Colon);
    		stream.write(p, 0, p.length);
    		stream.write(__Semicolon);
    	}
    
    	private static void writeBoolean(ByteArrayOutputStream stream, byte b) {
    		stream.write(__b);
    		stream.write(__Colon);
    		stream.write(b);
    		stream.write(__Semicolon);
    	}
    
    	private static void writeInteger(ByteArrayOutputStream stream, byte[] i) {
    		stream.write(__i);
    		stream.write(__Colon);
    		stream.write(i, 0, i.length);
    		stream.write(__Semicolon);
    	}
    
    	private static void writeDouble(ByteArrayOutputStream stream, byte[] d) {
    		stream.write(__d);
    		stream.write(__Colon);
    		stream.write(d, 0, d.length);
    		stream.write(__Semicolon);
    	}
    
    	private static void writeString(ByteArrayOutputStream stream, byte[] s) {
    		byte[] slen = getBytes(new Integer(s.length));
    
    		stream.write(__s);
    		stream.write(__Colon);
    		stream.write(slen, 0, slen.length);
    		stream.write(__Colon);
    		stream.write(__Quote);
    		stream.write(s, 0, s.length);
    		stream.write(__Quote);
    		stream.write(__Semicolon);
    	}
    
    	private static int writeArray(ByteArrayOutputStream stream, Object a,
    			HashMap ht, int hv, String charset) {
    		int len = Array.getLength(a);
    		byte[] alen = getBytes(new Integer(len));
    
    		stream.write(__a);
    		stream.write(__Colon);
    		stream.write(alen, 0, alen.length);
    		stream.write(__Colon);
    		stream.write(__LeftB);
    		for (int i = 0; i < len; i++) {
    			writeInteger(stream, getBytes(new Integer(i)));
    			hv = serialize(stream, Array.get(a, i), ht, hv, charset);
    		}
    		stream.write(__RightB);
    		return hv;
    	}
    
    	private static int writeArrayList(ByteArrayOutputStream stream,
    			ArrayList a, HashMap ht, int hv, String charset) {
    		int len = a.size();
    		byte[] alen = getBytes(new Integer(len));
    
    		stream.write(__a);
    		stream.write(__Colon);
    		stream.write(alen, 0, alen.length);
    		stream.write(__Colon);
    		stream.write(__LeftB);
    		for (int i = 0; i < len; i++) {
    			writeInteger(stream, getBytes(new Integer(i)));
    			hv = serialize(stream, a.get(i), ht, hv, charset);
    		}
    		stream.write(__RightB);
    		return hv;
    	}
    
    	private static int writeHashMap(ByteArrayOutputStream stream, HashMap h,
    			HashMap ht, int hv, String charset) {
    		int len = h.size();
    		byte[] hlen = getBytes(new Integer(len));
    
    		stream.write(__a);
    		stream.write(__Colon);
    		stream.write(hlen, 0, hlen.length);
    		stream.write(__Colon);
    		stream.write(__LeftB);
    		for (Iterator keys = h.keySet().iterator(); keys.hasNext();) {
    			Object key = keys.next();
    
    			if ((key instanceof Byte) || (key instanceof Short)
    					|| (key instanceof Integer)) {
    				writeInteger(stream, getBytes(key));
    			} else if (key instanceof Boolean) {
    				writeInteger(
    						stream,
    						new byte[] { ((Boolean) key).booleanValue() ? __1 : __0 });
    			} else {
    				writeString(stream, getBytes(key, charset));
    			}
    			hv = serialize(stream, h.get(key), ht, hv, charset);
    		}
    		stream.write(__RightB);
    		return hv;
    	}
    
    	private static int writeObject(ByteArrayOutputStream stream, Object obj,
    			HashMap ht, int hv, String charset) {
    		Class cls = obj.getClass();
    
    		if (obj instanceof java.io.Serializable) {
    			byte[] className = getBytes(getClassName(cls), charset);
    			byte[] classNameLen = getBytes(new Integer(className.length));
    
    			if (obj instanceof org.phprpc.util.Serializable) {
    				byte[] cs = ((org.phprpc.util.Serializable) obj).serialize();
    				byte[] cslen = getBytes(new Integer(cs.length));
    
    				stream.write(__C);
    				stream.write(__Colon);
    				stream.write(classNameLen, 0, classNameLen.length);
    				stream.write(__Colon);
    				stream.write(__Quote);
    				stream.write(className, 0, className.length);
    				stream.write(__Quote);
    				stream.write(__Colon);
    				stream.write(cslen, 0, cslen.length);
    				stream.write(__Colon);
    				stream.write(__LeftB);
    				stream.write(cs, 0, cs.length);
    				stream.write(__RightB);
    			} else {
    				Method __sleep;
    
    				try {
    					__sleep = cls.getMethod("__sleep", new Class[0]);
    				} catch (Exception e) {
    					__sleep = null;
    				}
    				int fl = 0;
    				Field[] f;
    
    				if (__sleep != null) {
    					String[] fieldNames;
    
    					try {
    						__sleep.setAccessible(true);
    						fieldNames = (String[]) __sleep.invoke(obj,
    								new Object[0]);
    					} catch (Exception e) {
    						fieldNames = null;
    					}
    					f = getFields(obj, fieldNames);
    				} else {
    					f = getFields(obj);
    				}
    				AccessibleObject.setAccessible(f, true);
    				byte[] flen = getBytes(new Integer(f.length));
    
    				stream.write(__O);
    				stream.write(__Colon);
    				stream.write(classNameLen, 0, classNameLen.length);
    				stream.write(__Colon);
    				stream.write(__Quote);
    				stream.write(className, 0, className.length);
    				stream.write(__Quote);
    				stream.write(__Colon);
    				stream.write(flen, 0, flen.length);
    				stream.write(__Colon);
    				stream.write(__LeftB);
    				for (int i = 0, len = f.length; i < len; i++) {
    					int mod = f[i].getModifiers();
    
    					if (Modifier.isPublic(mod)) {
    						writeString(stream, getBytes(f[i].getName(), charset));
    					} else if (Modifier.isProtected(mod)) {
    						writeString(stream,
    								getBytes("*" + f[i].getName(), charset));
    					} else {
    						writeString(
    								stream,
    								getBytes(
    										""
    												+ getClassName(f[i]
    														.getDeclaringClass())
    												+ "" + f[i].getName(), charset));
    					}
    					Object o;
    
    					try {
    						o = f[i].get(obj);
    					} catch (Exception e) {
    						o = null;
    					}
    					hv = serialize(stream, o, ht, hv, charset);
    				}
    				stream.write(__RightB);
    			}
    		} else {
    			writeNull(stream);
    		}
    		return hv;
    	}
    
    	private static byte[] getBytes(Object obj) {
    		try {
    			return obj.toString().getBytes("US-ASCII");
    		} catch (Exception e) {
    			return obj.toString().getBytes();
    		}
    	}
    
    	private static byte[] getBytes(Object obj, String charset) {
    		try {
    			return obj.toString().getBytes(charset);
    		} catch (Exception e) {
    			return obj.toString().getBytes();
    		}
    	}
    
    	private static String getString(byte[] data, String charset) {
    		try {
    			return new String(data, charset);
    		} catch (Exception e) {
    			return new String(data);
    		}
    	}
    
    	private static Class getClass(String className) {
    		try {
    			Class cls = Class.forName(className);
    
    			return cls;
    		} catch (Exception e) {
    		}
    		for (int i = 0; i < __packages.length; i++) {
    			try {
    				Class cls = Class.forName(__packages[i].getName() + "."
    						+ className);
    
    				return cls;
    			} catch (Exception e) {
    			}
    		}
    		return null;
    	}
    
    	private static String getClassName(Class cls) {
    		return cls.getName().substring(cls.getPackage().getName().length() + 1);
    	}
    
    	private static Field getField(Object obj, String fieldName) {
    		Class cls = obj.getClass();
    
    		while (cls != null) {
    			try {
    				Field result = cls.getDeclaredField(fieldName);
    				int mod = result.getModifiers();
    
    				if (Modifier.isFinal(mod) || Modifier.isStatic(mod)) {
    					return null;
    				}
    				return result;
    			} catch (Exception e) {
    			}
    			cls = cls.getSuperclass();
    		}
    		return null;
    	}
    
    	private static Field[] getFields(Object obj, String[] fieldNames) {
    		if (fieldNames == null) {
    			return getFields(obj);
    		}
    		int n = fieldNames.length;
    		ArrayList fields = new ArrayList(n);
    
    		for (int i = 0; i < n; i++) {
    			Field f = getField(obj, fieldNames[i]);
    
    			if (f != null) {
    				fields.add(f);
    			}
    		}
    		return (Field[]) fields.toArray(new Field[0]);
    	}
    
    	private static Field[] getFields(Object obj) {
    		ArrayList fields = new ArrayList();
    		Class cls = obj.getClass();
    
    		while (cls != null) {
    			Field[] fs = cls.getDeclaredFields();
    
    			for (int i = 0; i < fs.length; i++) {
    				int mod = fs[i].getModifiers();
    
    				if (!Modifier.isFinal(mod) && !Modifier.isStatic(mod)) {
    					fields.add(fs[i]);
    				}
    			}
    			cls = cls.getSuperclass();
    		}
    		return (Field[]) fields.toArray(new Field[0]);
    	}
    
    	public static Object newInstance(Class cls) {
    		try {
    			Constructor ctor = cls.getConstructor(new Class[0]);
    			int mod = ctor.getModifiers();
    
    			if (Modifier.isPublic(mod)) {
    				return ctor.newInstance(new Object[0]);
    			}
    		} catch (Exception e) {
    		}
    		try {
    			Constructor ctor = cls.getConstructor(new Class[] { Integer.TYPE });
    			int mod = ctor.getModifiers();
    
    			if (Modifier.isPublic(mod)) {
    				return ctor.newInstance(new Object[] { new Integer(0) });
    			}
    		} catch (Exception e) {
    		}
    		try {
    			Constructor ctor = cls.getConstructor(new Class[] { Boolean.TYPE });
    			int mod = ctor.getModifiers();
    
    			if (Modifier.isPublic(mod)) {
    				return ctor.newInstance(new Object[] { new Boolean(false) });
    			}
    		} catch (Exception e) {
    		}
    		try {
    			Constructor ctor = cls.getConstructor(new Class[] { String.class });
    			int mod = ctor.getModifiers();
    
    			if (Modifier.isPublic(mod)) {
    				return ctor.newInstance(new Object[] { "" });
    			}
    		} catch (Exception e) {
    		}
    		Field[] f = cls.getFields();
    
    		for (int i = 0; i < f.length; i++) {
    			if (f[i].getType() == cls && Modifier.isStatic(f[i].getModifiers())) {
    				try {
    					return f[i].get(null);
    				} catch (Exception e) {
    				}
    			}
    		}
    		Method[] m = cls.getMethods();
    
    		for (int i = 0; i < m.length; i++) {
    			if (m[i].getReturnType() == cls
    					&& Modifier.isStatic(m[i].getModifiers())) {
    				try {
    					return m[i].invoke(null, new Object[0]);
    				} catch (Exception e) {
    				}
    				try {
    					return m[i].invoke(null, new Object[] { new Integer(0) });
    				} catch (Exception e) {
    				}
    				try {
    					return m[i].invoke(null,
    							new Object[] { new Boolean(false) });
    				} catch (Exception e) {
    				}
    				try {
    					return m[i].invoke(null, new Object[] { "" });
    				} catch (Exception e) {
    				}
    			}
    		}
    		return null;
    	}
    
    	public static Number cast(Number n, Class destClass) {
    		if (destClass == Byte.class) {
    			return new Byte(n.byteValue());
    		}
    		if (destClass == Short.class) {
    			return new Short(n.shortValue());
    		}
    		if (destClass == Integer.class) {
    			return new Integer(n.intValue());
    		}
    		if (destClass == Long.class) {
    			return new Long(n.longValue());
    		}
    		if (destClass == Float.class) {
    			return new Float(n.floatValue());
    		}
    		if (destClass == Double.class) {
    			return new Double(n.doubleValue());
    		}
    		return n;
    	}
    
    	public static Object cast(Object obj, Class destClass) {
    		if (obj == null || destClass == null) {
    			return obj;
    		} else if (obj.getClass() == destClass) {
    			return obj;
    		} else if (obj instanceof Number) {
    			return cast((Number) obj, destClass);
    		} else if ((obj instanceof String) && destClass == Character.class) {
    			return new Character(((String) obj).charAt(0));
    		} else if ((obj instanceof ArrayList) && destClass.isArray()) {
    			return toArray((ArrayList) obj, destClass.getComponentType());
    		} else if ((obj instanceof ArrayList) && destClass == HashMap.class) {
    			return toHashMap((ArrayList) obj);
    		} else {
    			return obj;
    		}
    	}
    
    	private static HashMap toHashMap(ArrayList a) {
    		int n = a.size();
    		HashMap h = new HashMap(n);
    
    		for (int i = 0; i < n; i++) {
    			h.put(new Integer(i), a.get(i));
    		}
    		return h;
    	}
    
    	private static Object toArray(ArrayList obj, Class componentType) {
    		int n = obj.size();
    		Object a = Array.newInstance(componentType, n);
    
    		for (int i = 0; i < n; i++) {
    			Array.set(a, i, cast(obj.get(i), componentType));
    		}
    		return a;
    	}
    
    	private static int getPos(ByteArrayInputStream stream) {
    		try {
    			Field pos = stream.getClass().getDeclaredField("pos");
    
    			pos.setAccessible(true);
    			return pos.getInt(stream);
    		} catch (Exception e) {
    			return 0;
    		}
    	}
    
    	private static void setPos(ByteArrayInputStream stream, int p) {
    		try {
    			Field pos = stream.getClass().getDeclaredField("pos");
    
    			pos.setAccessible(true);
    			pos.setInt(stream, p);
    		} catch (Exception e) {
    		}
    	}
    
    	public static Object unserialize(byte[] ss) throws IllegalAccessException {
    		return unserialize(ss, null, "UTF-8");
    	}
    
    	public static Object unserialize(byte[] ss, String charset)
    			throws IllegalAccessException {
    		return unserialize(ss, null, charset);
    	}
    
    	public static Object unserialize(byte[] ss, Class cls)
    			throws IllegalAccessException {
    		return unserialize(ss, cls, "UTF-8");
    	}
    
    	public static Object unserialize(byte[] ss, Class cls, String charset)
    			throws IllegalAccessException {
    		int hv = 1;
    		ByteArrayInputStream stream = new ByteArrayInputStream(ss);
    		Object result = unserialize(stream, new HashMap(), hv, new HashMap(),charset).value;
    
    		try {
    			stream.close();
    		} catch (Exception e) {
    		}
    		return cast(result, cls);
    	}
    
    	private static UnSerializeResult unserialize(ByteArrayInputStream stream,
    			HashMap ht, int hv, HashMap rt, String charset)
    			throws IllegalAccessException {
    		Object obj;
    
    		switch (stream.read()) {
    		case __N:
    			obj = readNull(stream);
    			ht.put(new Integer(hv++), obj);
    			return new UnSerializeResult(obj, hv);
    
    		case __b:
    			obj = readBoolean(stream);
    			ht.put(new Integer(hv++), obj);
    			return new UnSerializeResult(obj, hv);
    
    		case __i:
    			obj = readInteger(stream);
    			ht.put(new Integer(hv++), obj);
    			return new UnSerializeResult(obj, hv);
    
    		case __d:
    			obj = readDouble(stream);
    			ht.put(new Integer(hv++), obj);
    			return new UnSerializeResult(obj, hv);
    
    		case __s:
    			obj = readString(stream, charset);
    			ht.put(new Integer(hv++), obj);
    			return new UnSerializeResult(obj, hv);
    
    		case __U:
    			obj = readUnicodeString(stream);
    			ht.put(new Integer(hv++), obj);
    			return new UnSerializeResult(obj, hv);
    
    		case __r:
    			return readRef(stream, ht, hv, rt);
    
    		case __a:
    			return readArray(stream, ht, hv, rt, charset);
    
    		case __O:
    			return readObject(stream, ht, hv, rt, charset);
    
    		case __C:
    			return readCustomObject(stream, ht, hv, charset);
    
    		case __R:
    			return readPointRef(stream, ht, hv, rt);
    
    		default:
    			return null;
    		}
    	}
    
    	private static String readNumber(ByteArrayInputStream stream) {
    		StringBuffer sb = new StringBuffer();
    		int i = stream.read();
    
    		while ((i != __Semicolon) && (i != __Colon)) {
    			sb.append((char) i);
    			i = stream.read();
    		}
    		return sb.toString();
    	}
    
    	private static Object readNull(ByteArrayInputStream stream) {
    		stream.skip(1);
    		return null;
    	}
    
    	private static Boolean readBoolean(ByteArrayInputStream stream) {
    		stream.skip(1);
    		Boolean b = new Boolean(stream.read() == __1);
    
    		stream.skip(1);
    		return b;
    	}
    
    	private static Number readInteger(ByteArrayInputStream stream) {
    		stream.skip(1);
    		String i = readNumber(stream);
    
    		try {
    			return new Byte(i);
    		} catch (Exception e1) {
    			try {
    				return new Short(i);
    			} catch (Exception e2) {
    				return new Integer(i);
    			}
    		}
    	}
    
    	private static Number readDouble(ByteArrayInputStream stream) {
    		stream.skip(1);
    		String d = readNumber(stream);
    
    		if (d.equals(__NAN)) {
    			return new Double(Double.NaN);
    		}
    		if (d.equals(__INF)) {
    			return new Double(Double.POSITIVE_INFINITY);
    		}
    		if (d.equals(__NINF)) {
    			return new Double(Double.NEGATIVE_INFINITY);
    		}
    		try {
    			return new Long(d);
    		} catch (Exception e1) {
    			try {
    				Float f = new Float(d);
    
    				if (f.isInfinite()) {
    					return new Double(d);
    				} else {
    					return f;
    				}
    			} catch (Exception e2) {
    				return new Float(0);
    			}
    		}
    	}
    
    	private static String readString(ByteArrayInputStream stream, String charset) {
    		stream.skip(1);
    		int len = Integer.parseInt(readNumber(stream));
    
    		stream.skip(1);
    		byte[] buf = new byte[len];
    
    		stream.read(buf, 0, len);
    		String s = getString(buf, charset);
    
    		stream.skip(2);
    		return s;
    	}
    
    	private static String readUnicodeString(ByteArrayInputStream stream) {
    		stream.skip(1);
    		int l = Integer.parseInt(readNumber(stream));
    
    		stream.skip(1);
    		StringBuffer sb = new StringBuffer(l);
    		int c;
    
    		for (int i = 0; i < l; i++) {
    			if ((c = stream.read()) == __Slash) {
    				char c1 = (char) stream.read();
    				char c2 = (char) stream.read();
    				char c3 = (char) stream.read();
    				char c4 = (char) stream.read();
    
    				sb.append((char) (Integer.parseInt(new String(new char[] { c1,
    						c2, c3, c4 }), 16)));
    			} else {
    				sb.append((char) c);
    			}
    		}
    		stream.skip(2);
    		return sb.toString();
    	}
    
    	private static UnSerializeResult readRef(ByteArrayInputStream stream,
    			HashMap ht, int hv, HashMap rt) {
    		stream.skip(1);
    		Integer r = new Integer(readNumber(stream));
    
    		if (rt.containsKey(r)) {
    			rt.put(r, new Boolean(true));
    		}
    		Object obj = ht.get(r);
    
    		ht.put(new Integer(hv++), obj);
    		return new UnSerializeResult(obj, hv);
    	}
    
    	private static UnSerializeResult readPointRef(ByteArrayInputStream stream,
    			HashMap ht, int hv, HashMap rt) {
    		stream.skip(1);
    		Integer r = new Integer(readNumber(stream));
    
    		if (rt.containsKey(r)) {
    			rt.put(r, new Boolean(true));
    		}
    		Object obj = ht.get(r);
    
    		return new UnSerializeResult(obj, hv);
    	}
    
    	private static UnSerializeResult readArray(ByteArrayInputStream stream,
    			HashMap ht, int hv, HashMap rt, String charset)
    			throws IllegalAccessException {
    		stream.skip(1);
    		int n = Integer.parseInt(readNumber(stream));
    
    		stream.skip(1);
    		HashMap h = new HashMap(n);
    		ArrayList al = new ArrayList(n);
    		Integer r = new Integer(hv);
    
    		rt.put(r, new Boolean(false));
    		int p = getPos(stream);
    
    		ht.put(new Integer(hv++), h);
    		for (int i = 0; i < n; i++) {
    			Object key;
    
    			switch (stream.read()) {
    			case __i:
    				key = cast(readInteger(stream), Integer.class);
    				break;
    
    			case __s:
    				key = readString(stream, charset);
    				break;
    
    			case __U:
    				key = readUnicodeString(stream);
    				break;
    
    			default:
    				return null;
    			}
    			UnSerializeResult result = unserialize(stream, ht, hv, rt, charset);
    
    			hv = result.hv;
    			if (al != null) {
    				if ((key instanceof Integer)
    						&& (((Integer) key).intValue() == i)) {
    					al.add(result.value);
    				} else {
    					al = null;
    				}
    			}
    			h.put(key, result.value);
    		}
    		if (al != null) {
    			ht.put(r, al);
    			if (((Boolean) (rt.get(r))).booleanValue()) {
    				hv = r.intValue() + 1;
    				setPos(stream, p);
    				for (int i = 0; i < n; i++) {
    					int key;
    
    					switch (stream.read()) {
    					case __i:
    						key = ((Integer) cast(readInteger(stream),
    								Integer.class)).intValue();
    						break;
    
    					default:
    						return null;
    					}
    					UnSerializeResult result = unserialize(stream, ht, hv, rt,
    							charset);
    
    					hv = result.hv;
    					al.set(key, result.value);
    				}
    			}
    		}
    		rt.remove(r);
    		stream.skip(1);
    		return new UnSerializeResult(ht.get(r), hv);
    	}
    
    	private static UnSerializeResult readObject(ByteArrayInputStream stream,
    			HashMap ht, int hv, HashMap rt, String charset)
    			throws IllegalAccessException {
    		stream.skip(1);
    		int len = Integer.parseInt(readNumber(stream));
    
    		stream.skip(1);
    		byte[] buf = new byte[len];
    
    		stream.read(buf, 0, len);
    		String cn = getString(buf, charset);
    
    		stream.skip(2);
    		int n = Integer.parseInt(readNumber(stream));
    
    		stream.skip(1);
    		Class cls = getClass(cn);
    		Object o;
    
    		if (cls != null) {
    			if ((o = newInstance(cls)) == null) {
    				o = new HashMap(n);
    			}
    		} else {
    			o = new HashMap(n);
    		}
    		ht.put(new Integer(hv++), o);
    		for (int i = 0; i < n; i++) {
    			String key;
    
    			switch (stream.read()) {
    			case __s:
    				key = readString(stream, charset);
    				break;
    
    			case __U:
    				key = readUnicodeString(stream);
    				break;
    
    			default:
    				return null;
    			}
    			if (key.charAt(0) == (char) 0) {
    				key = key.substring(key.indexOf("", 1) + 1);
    			}
    			UnSerializeResult result = unserialize(stream, ht, hv, rt, charset);
    
    			hv = result.hv;
    			if (o instanceof HashMap) {
    				((HashMap) o).put(key, result.value);
    			} else {
    				Field f = getField(o, key);
    
    				f.setAccessible(true);
    				f.set(o, result.value);
    			}
    		}
    		stream.skip(1);
    		Method __wakeup = null;
    
    		try {
    			__wakeup = o.getClass().getMethod("__wakeup", new Class[0]);
    			__wakeup.invoke(o, new Object[0]);
    		} catch (Exception e) {
    		}
    		return new UnSerializeResult(o, hv);
    	}
    
    	private static UnSerializeResult readCustomObject(
    			ByteArrayInputStream stream, HashMap ht, int hv, String charset) {
    		stream.skip(1);
    		int len = Integer.parseInt(readNumber(stream));
    
    		stream.skip(1);
    		byte[] buf = new byte[len];
    
    		stream.read(buf, 0, len);
    		String cn = getString(buf, charset);
    
    		stream.skip(2);
    		int n = Integer.parseInt(readNumber(stream));
    
    		stream.skip(1);
    		Class cls = getClass(cn);
    		Object o;
    
    		if (cls != null) {
    			o = newInstance(cls);
    		} else {
    			o = null;
    		}
    		ht.put(new Integer(hv++), o);
    		if (o == null) {
    			stream.skip(n);
    		} else if (o instanceof org.phprpc.util.Serializable) {
    			byte[] b = new byte[n];
    
    			stream.read(b, 0, n);
    			((org.phprpc.util.Serializable) o).unserialize(b);
    		} else {
    			stream.skip(n);
    		}
    		stream.skip(1);
    		return new UnSerializeResult(o, hv);
    }
    

    将项目中使用的序列化和反序列化方法抽离出来,放在一个工具类里面了:
    SerializeUtil.java

    import java.io.UnsupportedEncodingException;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.apache.commons.lang3.StringUtils;
    
    import com.thinkgem.jeesite.common.utils.PHPSerializer;
    
    /**
     * 
     * 类描述:PHP序列化和反序列化工具
     * @author linmengmeng
     * 创建时间:2019年1月15日 下午4:06:58
     */
    public class SerializeUtil {
    
    	/**
    	 * 字符串序列化
    	 * @Title: serialize
    	 * @Description: 字符串序列化
    	 * @param cartIds
    	 * @throws
    	 * @return String    
    	 */
    	@SuppressWarnings("finally")
    	public static String serialize(String[] cartIds) {
    		String str = "";
    		Map<String, Object> mapImage = new HashMap<String, Object>();
    		Map<Integer, String> fileNameList = new HashMap<Integer, String>();
    		try {
    			for (int i = 0; i < cartIds.length; i++) {
    				fileNameList.put(i + 1, cartIds[i]);
    			}
    			mapImage.put("buyer", fileNameList);
    			byte[] a = PHPSerializer.serialize(mapImage);
    			str = new String(a, "UTF-8");
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    		} finally {
    			return str;
    		}
    	}
    	
    	/**
    	 * 将字符串反序列
    	 * @Title: unserialize
    	 * @Description: 将字符串反序列
    	 * @param content
    	 * @return  
    	 * @throws
    	 * @return String    
    	 */
    	@SuppressWarnings({ "finally", "unchecked" })	
    	public static String unserialize(String content){
    		String string = null;
    		if (StringUtils.isEmpty(content)) {
    			return string;
    		}
    		try {
    			HashMap<String, Map<Integer, String>> hashMap =  (HashMap<String, Map<Integer, String>>) PHPSerializer.unserialize(content.getBytes());
    			Map<Integer, String> map = hashMap.get("buyer");
    			Collection<String> values = map.values();
    			String[] strings = values.toArray(new String[values.size()]);
    			string = StringUtils.join(strings, ',');
    		} catch (IllegalAccessException e) {
    			e.printStackTrace();
    		}finally {
    			return string;
    		}
    	}
    
    	public static void main(String[] args) {
    		String[] cartIds = {"06008816930683722.jpg", "06008816930681525.jpg"};
    		String serialize = serialize(cartIds);
    		System.out.println(serialize);
    		String unserialize = unserialize(serialize);
    		System.out.println(unserialize);
    		/*String unserialize = unserialize("N;");
    		System.out.println(unserialize);*/
    	}
    }
    /**Output:
    a:1:{s:5:"buyer";a:2:{i:1;s:21:"06008816930683722.jpg";i:2;s:21:"06008816930681525.jpg";}}
    06008816930681525.jpg,06008816930683722.jpg
    */
    

    SerializeUtil 中的序列化和反序列化的方法是自定义的,如果不想这么麻烦可以直接参考这篇博客:https://www.cnblogs.com/ctaixw/p/6213910.html
    工具类中的反序列化方法,就是参考这篇博客倒腾出来的。也可以直接使用上面PHPSerializer.java中的序列化和反序列化的方法:

    	public static void main(String[] args) {
    		String[] cartIds = {"06008816930683722.jpg", "06008816930681525.jpg"};
    		byte[] serialize = PHPSerializer.serialize(cartIds);
    		String serializeString = new String(serialize);
    		System.out.println(serializeString);
    		try {
    			try {
    				//Object unserialize = PHPSerializer.unserialize(serializeString.getBytes("utf-8"));
    				@SuppressWarnings("unchecked")
    				List<String> unserialize = (List<String>) PHPSerializer.unserialize(serializeString.getBytes("utf-8"));
    				System.out.println(unserialize);
    				String jsonString = JSON.toJSONString(unserialize);
    				System.out.println(jsonString);
    			} catch (UnsupportedEncodingException e) {
    				e.printStackTrace();
    			}
    		} catch (IllegalAccessException e) {
    			e.printStackTrace();
    		}
    	}
    

    输出:

    a:2:{i:0;s:21:"06008816930683722.jpg";i:1;s:21:"06008816930681525.jpg";}
    [06008816930683722.jpg, 06008816930681525.jpg]
    ["06008816930683722.jpg","06008816930681525.jpg"]
    

    在注释掉的这句Object unserialize = PHPSerializer.unserialize(serializeString.getBytes("utf-8"));中可以直接当成Object类型进行输出,就可以看到原数据是从哪一种类型序列化而来的了。在将离职的同事序列化的数据给反序列回来的时候,这个输出点醒了我。

    问题总是一个挨一个的过来了,现在有个问题就是,因为和PHP那边使用了同一个数据库,有些数据需要序列化一下存进去,然后他们那边反序列化之后拿出来用。

    我们这边将参数序列化之后放进去,但是PHP那边却不能用。

    刚开始我还以为是我们序列化的方式和PHP那边的反序列化方式不配套,不能序列和反序列之后使用的问题导致的。一直在纠结这个,今天一大早就在跟PHP那边验证这个序列化和反序列化的问题。

    我这边找一个字符串,序列化之后,发给PHP那边,然后他们直接反序列化,刚开始都有点蒙蔽,试了好几遍才试出来,是配套的,也就是我们这边序列化之后的数据,他们那边反序列化一下,是可以拿到原数据的。

    但是为什么用到项目里面就不行了呢,就很不解了。

    早上测试时只是用的字符串测试的,是有来有回,正常的。然后我直接从数据库里面拿他们将数组序列化之后的数据进行反序列化,是可以出来数据的,反序列化出来是一个Map类型的,然后我又试了一次直接将控制台打印的map数据,直接塞在一个字符串里面,然后序列化,把序列化之后的数据给PHP那边发过去,然后他们那边解析不出来数据,到这里我就想着这没法用啊,类型不一致什么的。。。。,我们序列化的数据,他们解析不出来,他们序列化的数据,我这边解析报错,这还怎么玩。。。。。就这个潜意识导致我浪费了半天的时间。
    下午来了之后,项目中的序列化的内容,看到我们这边是将数据放在map里面,然后对map进行序列化,然后将数据存进数据库的。我就是了一下自己随便写了一个map,序列化一下,发给PHP那边,让他们解析试试,结果不行,我就仔细对比了一下,发现他们那边存的数据,跟我们这边的原数据map里面的key的名称不一样。。。。。

    到这里才算突然醒悟,参数名不一致了,即使他们那边反序列化成功了,也没法正常用的,那就按照他们那边的格式,将map里面的参数名都参照,将他们序列化的数据反序列化后的map里面的key,这样果然可行。。。。。

    啰嗦了这么多,其实就是我们这边对原数据map进行序列化的时候,需要保证map里面的key和他们那边的原数据数组里的名称对应,这样才能有来有回。
    贴一张图,看图会更清楚一些。
    在这里插入图片描述

    展开全文
    linmengmeng_1314 2019-01-15 21:16:46
  • 再创建一个序列化和序列化的工具类 public class SerializationUtil { //.bin 后缀代表二进制文件 private static String FILE_NAME = "D:/obj.bin" ; /** * 序列化 */ public ...

    先创建一个实体类,实现Serializable接口

    public class Person implements Serializable {
    	
    	private static final long serialVersionUID = 8428798474641047929L;
    	
    	private String name;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    }
    

    再创建一个序列化和反序列化的工具类

    public class SerializationUtil {
    	
    	//.bin后缀代表二进制文件
    	private static String FILE_NAME = "D:/obj.bin";
    	
    	/**
    	 * 序列化
    	 */
    	public static void writeObject(Serializable s) {
    		try {
    			ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME));
    			oos.writeObject(s);
    			oos.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	/**
    	 * 反序列化
    	 */
    	public static Object readObject() {
    		Object obj = null;
    		
    		try {
    			ObjectInput input = new ObjectInputStream(new FileInputStream(FILE_NAME));
    			obj = input.readObject();
    			input.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return obj;
    	}
    }
    

    然后main方法测试

    public class Main {
    
    	public static void main(String[] args) {
    		
    		//序列化
    		Person person = new Person();
    		person.setName("混世魔王");
    		SerializationUtil.writeObject(person);
    		
    		Person p = (Person) SerializationUtil.readObject();
    		System.out.println("name = " + p.getName());
    	}
    
    }
    展开全文
    tl2871761577 2018-05-25 10:42:22
  • caomiao2006 2016-06-05 12:21:38
  • sinat_32955803 2016-05-05 13:51:28
  • laifu007 2017-10-18 14:59:41
  • lingzhm 2015-04-14 21:02:32
  • jiandabang 2020-02-27 22:16:52
  • hy_coming 2019-05-17 22:30:00
  • lqzkcx3 2018-03-11 20:59:16
  • 17.58MB weixin_42101237 2021-05-09 03:06:31
  • qq_22260641 2017-04-24 10:21:54
  • hemeinvyiqiluoben 2018-10-14 20:57:23