精华内容
下载资源
问答
  • /// /// 通用序列化器 /// public class CommonSerialize { private static readonly IFormatter _formatter = new BinaryFormatter(); /// /// 反序列化 /// /
    /// <summary>
        /// 通用序列化器
        /// </summary>
        public class CommonSerialize
        {
            private static readonly IFormatter _formatter = new BinaryFormatter();
    
            /// <summary>
            /// 反序列化
            /// </summary>
            /// <param name="data">数据流</param>
            /// <returns>对象</returns>
            public static object Deserialize(byte[] data)
            {
                using (var stream = new MemoryStream(data))
                {
                   return _formatter.Deserialize(stream);
                }
            }
    
            /// <summary>
            /// 序列化
            /// </summary>
            /// <param name="o">对象</param>
            /// <returns>数据流</returns>
            public static byte[] Serialize(object o)
            {
                using (var stream = new MemoryStream())
                {
                    _formatter.Serialize(stream, o);
                    return stream.ToArray();
                }           
            }
        }

    展开全文
  • 如果想把Avro集成到现有系统,用内存序列化比较好。 其他情况,考虑用Avro的数据文件格式。 Avro官网上对数据文件格式的序列化讲的很清楚,这次不在赘述,只是介绍一下在内存中如何序列化。 我们以一个简单的Avro...

    最近项目中要用Avro对发送到Kafka中的数据进行序列化, 用Avro进行序列化可以有两种方式: 一种是在内存中序列化,另一种是数据文件格式。

    改怎么选择呢?

    如果想把Avro集成到现有系统,用内存序列化比较好。

    其他情况,考虑用Avro的数据文件格式。

    Avro官网上对数据文件格式的序列化讲的很清楚,这次不在赘述,只是介绍一下在内存中如何序列化。

    我们以一个简单的Avro模式为例

    {

      “type":"record",

      "name":"Pair",

      "doc":"A pair of strings.",

      "fields": [

           {"name":"left", "type":"string"},

          {"name":"right", "type":"string"}

         ]

    }

    将这一模式存贮在一个路劲下(一般是resources路劲下),并命名为Pair.avsc(avsc是Avro模式文件的常用扩展名).

    Schema schema= Schema.parse(getClass().getResourceAsStream("Pair.avsc"); //声明要加载的模式

    //创建Avro记录的实例,为记录的String字段构建了一个Avro Utf8实例

    GenericRecord datum=new GenericData.Record(schema);

    datum.put("left",new Utf8("L"));

    datum.put("right",new Utf8("R"));

    //将记录序列化到输出流中

    ByteArrayOutputStream out=new ByteArrayOutputStream();

    DatumWriter<GenericRecord> write=new GenericDatumWriter<GenericRecord>(schema);//DatumWriter 将数据对象翻译成Encoder对象可以理解的类型,

    Encoder encoder= new BinaryEncoder(out);//然后由Encoder写到数据流。

    write.write(datum,encoder);

    encoder.flush();

    out.close();


    //反序列化

    DatumReader<GenericRecord> reder=new GenericDatumReader<GenericRecord>(schema);

    Decoder decoder=DecoderFactory.defaultFactory().createBinaryDecoder(out.toByteArray(),null);

    GenericRecord result=reader.read(null,decoder);

    assertThat(result.get("left").toString(),is("L"));

    assertThat(result.get("right").toString,is("R"));





    展开全文
  • 遇到这个 Java Serializable 序列化这个接口,我们可能会有如下的问题a,什么叫序列化和反序列化 b,作用。为啥要实现这个 Serializable 接口,也就是为啥要序列化 c,serialVersionUID 这个的值到底是在怎么设置的...

    遇到这个 Java Serializable 序列化这个接口,我们可能会有如下的问题
    a,什么叫序列化和反序列化
    b,作用。为啥要实现这个 Serializable 接口,也就是为啥要序列化
    c,serialVersionUID 这个的值到底是在怎么设置的,有什么用。有的是1L,有的是一长串数字,迷惑ing。

    我刚刚见到这个关键字 Serializable 的时候,就有如上的这么些问题。

    在处理这个问题之前,你要先知道一个问题,这个比较重要。
    这个Serializable接口,以及相关的东西,全部都在 Java io 里面的。
     

    1,序列化和反序列化的概念

    序列化:把对象转换为字节序列的过程称为对象的序列化。
    反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

    上面是专业的解释,现在来点通俗的解释。在代码运行的时候,我们可以看到很多的对象(debug过的都造吧),
    可以是一个,也可以是一类对象的集合,很多的对象数据,这些数据中,
    有些信息我们想让他持久的保存起来,那么这个就叫序列化。
    就是把内存里面的这些对象给变成一连串的字节(bytes)描述的过程。
    常见的就是变成文件
    我不序列化也可以保存文件啥的呀,有什么影响呢?我也是这么问的。

    2,什么情况下需要序列化 

    当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
    当你想用套接字在网络上传送对象的时候;
    当你想通过RMI传输对象的时候;

    (老实说,上面的几种,我可能就用过个存数据库的。)

     

    3,java如何实现序列化

    实现Serializable接口即可

    上面这些理论都比较简单,下面实际代码看看这个序列化到底能干啥,以及会产生的bug问题。

    先上对象代码,飞猪.java

    package com.lxk.model;
    
    import java.io.Serializable;
    
    /**
     * @author lxk on 2017/11/1
     */
    public class FlyPig implements Serializable {
        //private static final long serialVersionUID = 1L;
        private static String AGE = "269";
        private String name;
        private String color;
        transient private String car;
    
        //private String addTip;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    
        public String getCar() {
            return car;
        }
    
        public void setCar(String car) {
            this.car = car;
        }
    
        //public String getAddTip() {
        //    return addTip;
        //}
        //
        //public void setAddTip(String addTip) {
        //    this.addTip = addTip;
        //}
    
        @Override
        public String toString() {
            return "FlyPig{" +
                    "name='" + name + '\'' +
                    ", color='" + color + '\'' +
                    ", car='" + car + '\'' +
                    ", AGE='" + AGE + '\'' +
                    //", addTip='" + addTip + '\'' +
                    '}';
        }
    }
    

    注意下,注释的代码,是一会儿要各种情况下使用的。

    下面就是main方法啦

    package com.lxk.test;
    
    import com.lxk.model.FlyPig;
    
    import java.io.*;
    
    /**
     * 序列化测试
     *
     * @author lxk on 2017/11/1
     */
    public class SerializableTest {
        public static void main(String[] args) throws Exception {
            serializeFlyPig();
            FlyPig flyPig = deserializeFlyPig();
            System.out.println(flyPig.toString());
    
        }
    
        /**
         * 序列化
         */
        private static void serializeFlyPig() throws IOException {
            FlyPig flyPig = new FlyPig();
            flyPig.setColor("black");
            flyPig.setName("naruto");
            flyPig.setCar("0000");
            // ObjectOutputStream 对象输出流,将 flyPig 对象存储到E盘的 flyPig.txt 文件中,完成对 flyPig 对象的序列化操作
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("d:/flyPig.txt")));
            oos.writeObject(flyPig);
            System.out.println("FlyPig 对象序列化成功!");
            oos.close();
        }
    
        /**
         * 反序列化
         */
        private static FlyPig deserializeFlyPig() throws Exception {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:/flyPig.txt")));
            FlyPig person = (FlyPig) ois.readObject();
            System.out.println("FlyPig 对象反序列化成功!");
            return person;
        }
    }
    

    对上面的2个操作文件流的类的简单说明

    ObjectOutputStream代表对象输出流:

    它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

    ObjectInputStream代表对象输入流:

    它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

    具体怎么看运行情况。

    第一种:上来就这些代码,不动,直接run,看效果。

    实际运行结果,他会在 d:/flyPig.txt 生成个文件。

    从运行结果上看:

    1,他实现了对象的序列化和反序列化。

    2,transient 修饰的属性,是不会被序列化的。我设置的奥迪四个圈的车不见啦,成了null。my god。

    3,你先别着急说,这个静态变量AGE也被序列化啦。这个得另测。

     

    第二种:为了验证这个静态的属性能不能被序列化和反序列化,可如下操作。

        public static void main(String[] args) throws Exception {
            serializeFlyPig();
            //FlyPig flyPig = deserializeFlyPig();
            //System.out.println(flyPig.toString());
        }

    这个完了之后,意思也就是说,你先序列化个对象到文件了。这个对象是带静态变量的static。

    现在修改flyPig类里面的AGE的值,给改成26吧。

    然后,看下图里面的运行代码和执行结果。

    可以看到,刚刚序列化的269,没有读出来。而是刚刚修改的26,如果可以的话,应该是覆盖这个26,是269才对。

    所以,得出结论,这个静态static的属性,他不序列化。

     

    第三种:示范这个 serialVersionUID 的作用和用法

    最暴力的改法,直接把model的类实现的这个接口去掉。然后执行后面的序列化和反序列化的方法。直接报错。

    抛异常:NotSerializableException

    这个太暴力啦,不推荐这么干。

    然后就是,还和上面的操作差不多,先是单独执行序列化方法。生成文件。
    然后,打开属性 addTip ,这之后,再次执行反序列化方法,看现象。

    抛异常:InvalidClassException  详情如下。

    InvalidClassException: com.lxk.model.FlyPig; 
    local class incompatible: 
    stream classdesc serialVersionUID = -3983502914954951240, 
    local class serialVersionUID = 7565838717623951575

    解释一下:

    因为我再model里面是没有明确的给这个 serialVersionUID 赋值,但是,Java会自动的给我赋值的,

    这个值跟这个model的属性相关计算出来的。

    我保存的时候,也就是我序列化的时候,那时候还没有这个addTip属性呢,

    所以,自动生成的serialVersionUID 这个值,

    在我反序列化的时候Java自动生成的这个serialVersionUID值是不同的,他就抛异常啦。

    (你还可以反过来,带ID去序列化,然后,没ID去反序列化。也是同样的问题。)

    再来一次,就是先序列化,这个时候,把 private static final long serialVersionUID = 1L; 这行代码的注释打开。那个addTip属性先注释掉,序列化之后,再把这个属性打开,再反序列化。看看什么情况。

    这个时候,代码执行OK,一切正常。good。序列化的时候,是没的那个属性的,在发序列化的时候,对应的model多了个属性,但是,反序列化执行OK,没出异常。

     

    这个现象对我们有什么意义:

    老铁,这个意义比较大,首先,你要是不知道这个序列化是干啥的,万一他真的如开头所讲的那样存数据库(这个存db是否涉及到Java的序列化估计还的看什么数据库吧)啦,socket传输啦,rmi传输啦。虽然我也不知道这是干啥的。你就给model bean 实现了个这个接口,你没写这个 serialVersionUID 那么在后来扩展的时候,可能就会出现不认识旧数据的bug,那不就炸啦吗。回忆一下上面的这个出错情况。想想都可怕,这个锅谁来背? 

    所以,有这么个理论,就是在实现这个Serializable 接口的时候,一定要给这个 serialVersionUID 赋值,就是这么个问题。

    这也就解释了,我们刚刚开始编码的时候,实现了这个接口之后,为啥eclipse编辑器要黄色警告,需要添加个这个ID的值。而且还是一长串你都不知道怎么来的数字。

     

    下面解释这个 serialVersionUID 的值到底怎么设置才OK

    首先,你可以不用自己去赋值,Java会给你赋值,但是,这个就会出现上面的bug,很不安全,所以,还得自己手动的来。

    那么,我该怎么赋值,eclipse可能会自动给你赋值个一长串数字。这个是没必要的。

    可以简单的赋值个 1L,这就可以啦。。这样可以确保代码一致时反序列化成功。

    不同的serialVersionUID的值,会影响到反序列化,也就是数据的读取,你写1L,注意L大些。计算机是不区分大小写的,但是,作为观众的我们,是要区分1和L的l,所以说,这个值,闲的没事不要乱动,不然一个版本升级,旧数据就不兼容了,你还不知道问题在哪。。。

     

    下面是摘自 jdk api 文档里面关于接口 Serializable 的描述
    类通过实现 java.io.Serializable 接口以启用其序列化功能。
    未实现此接口的类将无法使其任何状态序列化或反序列化。
    可序列化类的所有子类型本身都是可序列化的。因为实现接口也是间接的等同于继承。
    序列化接口没有方法或字段,仅用于标识可序列化的语义。

    关于 serialVersionUID 的描述

    https://blog.csdn.net/qq_27093465?viewmode=contents

    (注意对比一下,这个截图的两段话,就是对应下面的2段中文。仔细看这2段话,就能解释43楼的问题,静态属性不会被序列化,但是却又有一个特殊的静态属性,会被序列化,没办法,这个静态属性是亲生的。自带的。)

    序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException。可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID:

    如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException。因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private 修饰符显示声明 serialVersionUID(如果可能),原因是这种声明仅应用于直接声明类 -- serialVersionUID 字段作为继承成员没有用处。数组类不能声明一个明确的 serialVersionUID,因此它们总是具有默认的计算值,但是数组类没有匹配 serialVersionUID 值的要求。

     

    最后更新一下

    1,(针对25楼的留言:序列化的类的所有成员变量是不是都要是基本类型或实现Serializable接口的类型?)

    当属性是对象的时候,如果这个对象,没实现序列化接口,那么上面的方法在序列化的时候就在执行oos.writeObject(flyPig)时候,报错了“Exception in thread "main" java.io.NotSerializableException: com.lxk.model.Bird”。然后给刚刚的属性的对象加上实现序列化的接口之后,上面的测试就正常通过了。你这个问题问的好。

    结论:要实现序列化的对象,所有涉及的引用,都需要实现序列化接口才可以。

    2,(38楼问,这个serialVersionUID的值在存数据库的时候,存哪里了?)

    大师兄

    大师兄

    好问题,答不上来呀!!!我也是郁闷了,那大概猜一下,数据库没有使用Java这一套序列化,而是不同db各自实现了一套自己的序列化,so,就跟Java的这个静态属性没关系啦。静态属性是不存db的。然后,你就发现,你即使没实现这个Java的序列化的接口,也可以正常的存db,取db。太机智了,这个解释,满分,为啥呢,这个serialVersionUID是Java给你提供的一个序列化和反序列化用的,你要是不使Java这一套的话,那就不需要考虑这个问题啦呀。在上面的测试代码里面也是使用这些个API去序列化以及反序列化的。???

    3,(43楼问的问题:既然要比较新旧serialVersionUID, 旧的serialVersionUID是不是也应该序列化到文件中, 但serialVersionUID是static类型的, 是不会被序列化到文件中的)

    这个serialVersionUID是jdk亲生的,你写或者不写,只要实现了接口,他就是存在的,在序列化的时候,他还真就序列化,存起来了。不然在反序列化的时候,就没的对比了嘛,因为他是亲生的,所以,咱手动添加的静态,和这个静态是不能比的。

     

    我写完文章,给自己点个赞,不过分吧,
    不过分,那我可就点啦啊。
    我先点为敬,你们随意。大家随意。不要客气。。。

    展开全文
  • 序列化与反序列化

    千次阅读 多人点赞 2018-10-06 21:44:30
    序列化的意义 序列化面临的挑战 基于JDK 序列化方式实现 序列化的高阶认识 serialVersionUID 的作用 静态变量序列化 父类的序列化 Transient 关键字 常见的序列化技术 JAVA序列化框架 XML 序列化框架 ...

    目录

    序列化的意义

    序列化面临的挑战

    基于JDK 序列化方式实现

    序列化的高阶认识

    serialVersionUID 的作用

    静态变量序列化

    父类的序列化

    Transient 关键字

    常见的序列化技术

    JAVA序列化框架

    XML 序列化框架

    JSON 序列化框架

    Hessian 序列化框架

    Protobuf 序列化框架

    序列化技术的选型


    序列化的意义

    Java 平台允许我们在内存中创建可复用的Java 对象,但一般情况下,只有当JVM 处于运行时,这些对象才可能存在,即这些对象的生命周期不会比JVM 的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java 对象序列化就能够帮助我们实现该功能。

    简单来说,序列化是把对象的状态信息转化为可存储或传输的形式过程,也就是把对象转化为字节序列的过程称为对象的序列化。反序列化是序列化的逆向过程,把字节数组反序列化为对象,把字节序列恢复为对象的过程成为对象的反序列化。

    序列化面临的挑战

    评价一个序列化算法优劣的两个重要指标是:

    一. 序列化以后的数据大小;

    二. 序列化操作本身的速度及系统资源开销(CPU、内存)。

    Java 语言本身提供了对象序列化机制,也是Java 语言本身最重要的底层机制之一。在Java 中,只要一个类实现了java.io.Serializable 接口,那么它就可以被序列化。

    基于JDK 序列化方式实现

    JDK 提供了Java 对象的序列化方式,主要通过输出流java.io.ObjectOutputStream 和输入流java.io.ObjectInputStream来实现。其中,被序列化的对象需要实现java.io.Serializable 接口。

    import java.io.*;
    import java.util.Date;
    
    public class ObjectSaver {
        public static void main(String[] args) throws Exception {        
            //序列化对象
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:\\temp.txt"));
            Customer customer = new Customer("张三", 24);    
            out.writeObject("你好!");    //写入字面值常量
            out.writeObject(new Date());    //写入匿名Date对象
            out.writeObject(customer);    //写入customer对象
            out.close();
    
            
            //反序列化对象
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\\temp.txt"));
            System.out.println("obj1 " + (String) in.readObject());    //读取字面值常量
            System.out.println("obj2 " + (Date) in.readObject());    //读取匿名Date对象
            Customer obj3 = (Customer) in.readObject();    //读取customer对象
            System.out.println("obj3 " + obj3);
            in.close();
        }
    }
    
    class Customer implements Serializable {
        private String name;
        private int age;
        public Customer(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String toString() {
            return "name=" + name + ", age=" + age;
        }
    }

    序列化的高阶认识

    serialVersionUID 的作用

    Java 的序列化机制是通过判断类的serialVersionUID 来验证版本一致性的。在进行反序列化时,JVM 会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID 进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。

    当实现java.io.Serializable 接口的类没有显式地定义一个serialVersionUID 变量时候,Java 序列化机制会根据编译的Class 自动生成一个唯一的serialVersionUID,这种情况下,如果Class 文件的类名、方法名、属性名等没有发生变化,只是增加空格、换行、注释等,就算再编译多次,serialVersionUID 也不会变化。

    静态变量序列化

    序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量。

    父类的序列化

    一. 当父类没有实现Serializable 接口,子类继承该父类并且实现了Serializable 接口,在反序列化该子类后,将无法获取到父类的属性值的;

    二. 当父类实现了Serializable 接口,子类将自动支持序列化功能,不需要再显式实现Serializable 接口;

    三. 当一个对象的实例变量引用了其他对象,序列化该对象时也会把引用对象进行序列化,但是前提是该引用对象必须实现了Serializable 接口。

    Transient 关键字

    Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,Transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。

    绕开Transient 机制实现自定义序列化

    /**
      * ObjectOutputStream使用了反射来寻找是否声明了该方法
      * 实现自定义的序列化操作
      */
    private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException
    
    /**
      * ObjectInputStream使用了反射来寻找是否声明了该方法
      * 实现自定义的反序列化操作
      */
    private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException
    
    /**
      * ObjectInputStream使用了反射来寻找是否声明了该方法
      * 在使用单例时,如果使用的不是枚举的实现形式,为了保证反序列化出来后的对象,不会破坏单例的情况
      * 使用该方法返回原有实例
      */
    private Object readResolve()

    以HashMap为例,为何HashMap要自己实现writeObject和readObject方法?

    由于大部分情况序列化和反序列化所在的机器是不同的,而序列化和反序列化的一个最基本的要求就是,反序列化之后的对象与序列化之前的对象是一致的。HashMap中,由于Node 的存放位置是根据Key的Hash值来计算,然后存放到数组中的,对于同一个Key 在不同的JVM实现中计算得出的Hash值可能是不同的。 Hash值不同就有可能导致一个HashMap对象的反序列化结果与序列化之前的结果不一致。

    为了避免这个问题,HashMap采用了下面的方式来解决:

    一. 将可能会造成数据不一致的元素使用transient关键字修饰,从而避免JDK中默认序列化方法对该对象的序列化操作。不序列化的包括:Node<K,V>[] table,Set<Map.Entry<K,V>> entrySet,int size,int modCount。

    二. 自己实现writeObject和readObject方法。在序列化的时候不会将保存数据的数组序列化,而是将元素个数以及每个元素的Key和Value都进行序列化。在反序列化的时候,重新计算Key和Value的位置,重新填充一个数组,从而保证序列化和反序列化结果的一致性。 

    常见的序列化技术

    JAVA序列化框架

    使用JAVA 进行序列化有他的优点,也有他的缺点。

    优点:JAVA 语言本身提供,使用比较方便和简单。

    缺点:不支持跨语言处理、 性能相对不是很好,序列化以后产生的数据相对较大。

    XML 序列化框架

    XML 序列化的好处在于可读性好,方便阅读和调试。但是序列化以后的字节码文件比较大,而且效率不高,适用于对性能不高,而且QPS 较低的企业级内部系统之间的数据交换的场景,同时XML 又具有语言无关性,所以还可以用于异构系统之间的数据交换和协议。比如我们熟知的Webservice,就是采用XML 格式对数据进行序列化的。

    JSON 序列化框架

    JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,相对于XML 来说,JSON 的字节流更小,而且可读性也非常好。现在JSON 数据格式在企业运用是最普遍的。

    JSON 序列化常用的开源工具有很多:

    1. Jackson (https://github.com/FasterXML/jackson)
    2. 阿里开源的FastJson (https://github.com/alibaba/fastjon)
    3. Google 的GSON (https://github.com/google/gson)

    这几种json 序列化工具中,Jackson 与fastjson 要比GSON 的性能要好,但是Jackson、GSON 的稳定性要比Fastjson 好。而fastjson 的优势在于提供的api 非常容易使用。

    Hessian 序列化框架

    Hessian 是一个支持跨语言传输的二进制序列化协议,相对于Java 默认的序列化机制来说,Hessian 具有更好的性能和易用性,而且支持多种不同的语言。实际上Dubbo 采用的就是Hessian 序列化来实现,只不过Dubbo 对Hessian 进行了重构,性能更高。

    Protobuf 序列化框架

    Protobuf 是Google 的一种数据交换格式,它独立于语言、独立于平台。Google 提供了多种语言来实现,比如Java、C、Go、Python,每一种实现都包含了相应语言的编译器和库文件。Protobuf 使用比较广泛,主要是空间开销小和性能比较好,非常适合用于公司内部对性能要求高的RPC 调用。 另外由于解析性能比较高,序列化以后数据量相对较少,所以也可以应用在对象的持久化场景中。但是但是要使用Protobuf 会相对来说麻烦些,因为他有自己的语法,有自己的编译器。

    序列化技术的选型

    考虑因素:

    1. 序列化空间开销,也就是序列化产生的结果大小,这个影响到传输的性能;

    2. 序列化过程中消耗的时长,序列化消耗时间过长影响到业务的响应时间;

    3. 序列化协议是否支持跨平台,跨语言。因为现在的架构更加灵活,如果存在异构系统通信需求,那么这个是必须要考虑的;

    4. 可扩展性/兼容性,在实际业务开发中,系统往往需要随着需求的快速迭代来实现快速更新,这就要求我们采用的序列化协议基于良好的可扩展性/兼容性,比如在现有的序列化数据结构中新增一个业务字段,不会影响到现有的服务;

    5. 技术的流行程度,越流行的技术意味着使用的公司多,技术解决方案也相对成熟;

    6. 学习难度和易用性。

    选型建议:

    1. 对性能要求不高的场景,可以采用基于XML 的SOAP 协议;

    2. 对性能和间接性有比较高要求的场景,那么Hessian、Protobuf、Thrift、Avro 都可以。

    3. 基于前后端分离,或者独立的对外的api 服务,选用JSON 是比较好的,对于调试、可读性都很不错;

    4. Avro 设计理念偏于动态类型语言,那么这类的场景使用Avro 是可以的。

     

    展开全文
  • 许多后端检索server启动时候需要从文件加载到内存中构建索引,这个过程往往会消耗比较多的时间,通过提前将数据结构序列化为二进制文件,server 反序列化二进制文件的方式可以有效提升启动速度。
  • 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。 ...
  • 昨天晚上写了部分序列化,结果睡着了....今天继续完善.. 明天的四级反正是裸考了,无所谓了 。。。。 昨天写的那个只能实现单一类型的简单序列化 ,但是原理却是一样.. 今天这个可以实现不同的类的序列化,但是注意...
  • 序列化:按照某种规则,把内存中数据保存到文件中。 文件时一个字节序列,所以必须把数据转换成字节序列,输出到文件。 反序列化:从文件的字节序列恢复到内存并且还原原来的类型。 定义 serialization 序列化...
  • 将堆内存中Java对象转换为字节序列的过程称为序列化(Serialization),对象转换成字节序列便于将其存储在文件中或在网络上传输;将字节序列恢复为对象的过程称为反序列化(Deserialization)。 注意:序列化时,只...
  • hadoop序列化和反序列化

    千次阅读 2017-08-14 00:19:52
    序列化就是将内存中的对象或数据,转换成字节数组,以便于存储(持久化)和网络传输。 反序列化就是将字节数组转换成内存对象。 下面是对hadoop的序列化进行详细介绍,并且对hadoop的序列化方式和java原生的序列化...
  • Hadoop序列化与反序列化详解

    千次阅读 多人点赞 2019-11-11 21:03:38
    序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储到磁盘(持久化)和网络传输 反序列化就是将收到字节序列(或其他数据传输协议) 或者是磁盘的持久化数据,转换成内存中的对象 2.为什么要...
  • 序列化和反序列化的简单理解

    万次阅读 多人点赞 2016-05-10 19:24:12
    一、序列化和反序列化的概念  把对象转换为字节序列的过程称为对象的序列化。  把字节序列恢复为... 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是
  • java序列化和反序列化

    千次阅读 2018-07-20 18:26:41
    一:概念 序列化:将对象转化为二进制数据(字节序列)的过程成为序列化;... serialVersionUID:需要序列化的对象的成员属性,表示该对象的序列化版本id,反序列化的接收对象的serialVersionUID必须保持和序列化对...
  • 遇到这个 Java Serializable 序列化这个接口,我们可能会有如下的问题a,什么叫序列化和反序列化 b,作用。为啥要实现这个 Serializable 接口,也就是为啥要序列化 c,serialVersionUID 这个的值到底是在怎么设置的...
  • 序列化和反序列化

    千次阅读 2016-04-13 10:12:50
     使用序列化主要是因为跨平台和对象存储的需求,因为网络上只允许字符串或者二进制格式,而文件需要使用二进制流格式,如果想把一个内存中的对象存储下来就必须使用序列化转换为xml(字符串)、json(字符串)或二...
  • netty04-序列化序列化

    千次阅读 2018-02-07 17:22:18
    基础类型int在内存中的原始序列化 基于nio的序列化 基于netty的序列化 int类型序列化 int类型序列化方式有两种  大端序列:先写高位,在写低位  小端序列:先写低位,在写高位 左边是高位 右边是...
  • 神马是序列化呢,序列化就是把内存中的对象的状态信息,转换成字节序列以便于存储(持久化)和网络传输。(网络传输和硬盘持久化,你没有一定的手段来进行辨别这些字节序列是什么东西,有什么信息,这些字节序列就是...
  • JAVA序列化与反序列化

    千次阅读 2021-06-15 16:47:20
    JAVA序列化与反序列化 一、定义 序列化 把JAVA对象转换为字节序列的过程 反序列化 ... 于是 Web 容器就会把一些 Session 先序列化,让他们离开内存空间,序列化到硬盘中,当需要调用时,再把保存
  • 类型的序列化和反序列化

    千次阅读 2015-03-31 00:34:26
    1、序列化含义 .Net程序执行时,对象都驻留在内存中;内存中的对象如果需要传递给其他系统使用;或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化。本文只介绍xml序列化,其实序列化可以...
  • Java序列化与反序列化

    千次阅读 2016-05-11 12:21:36
    原文地址:... 目录[-] 序列化是干什么的 什么情况下需要序列化 序列化的几种方式 Object Serialize JSON化 Google ProtoBuf 序列化是干什么的 简单说就是为了保存在内存中的各种对象的状态
  • 深入分析Java的序列化与反序列化

    万次阅读 2016-02-03 23:01:35
    序列化是一种对象持久化的手段。普遍应用在网络传输、RMI等场景中。本文通过分析ArrayList的序列化来介绍Java序列化的相关内容。主要涉及到以下几个问题: 怎么实现Java的序列化 为什么实现了java.io....
  • Java实现 LeetCode 297 二叉树的序列化与反序列化

    万次阅读 多人点赞 2020-03-05 17:03:06
    序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。 请设计一个算法来实现...
  • 对比集中常见序列化工具性能以及内存占用java序列化alibaba jsonprotostuff测试方式:使用用户对象Customer,创建100万条对象,清空redis,逐条存入,分别记录序列化用时和redis读写用时public class Customer { ...
  • Java对象序列化与反序列化

    千次阅读 2016-07-25 22:59:18
    序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。为了提高serialVersionUID的独立性...
  • Hadoop序列化

    万次阅读 2020-04-23 22:18:10
    序列化:将内存中的对象装换成字节序列,以便于持久化存储到磁盘中以及网络传输。 反序列化:将收到的字节序列(或者其他数据传输协议)或者是磁盘的持久化数据,转换成内存中的对象。 为什么要序列化? 一般对象只...
  • Java实现 LeetCode 449 序列化和反序列化二叉搜索树

    万次阅读 多人点赞 2020-03-17 17:48:55
    序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。 设计一个算法来序列化和反序列化二叉搜索树。 对序列化...
  • c++ 序列化和反序列化

    千次阅读 2019-09-19 15:36:35
    c++ 序列化和反序列化什么是序列化?为什么要序列化?优点在哪里?C++对象序列化的四种方法...序列化指的是将一个内存对象转化成一串字节数据(存储在一个字节数组中),可用于保存到本地文件或网络传输。反序列...
  • 进行代码检查时,Coverity工具在进行json转换时,报Unsafe Deserialization错误,字面意思是不安全的反序列化,根本原因就是反序列化会有漏洞导致的。 看完下文反序列化漏洞的原理后,我们就知道该如何解决这个问题...
  • 序列化与反序列化技术选型

    千次阅读 2018-11-15 14:53:56
    文章目录一、使用场景二、概念三、参考指标四、序列化与反序列化协议通用组件流程图待序列化类XMLThriftProtobufAvro 一、使用场景 1、网络传输 2、加密、持久化 二、概念 1、通信协议中的位置 七层模型的表示层或者...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 405,589
精华内容 162,235
关键字:

内存序列化