精华内容
下载资源
问答
  • 1.序列化和反序列化序列化:把对象转换为字节序列的过程称为对象的序列化。(常见的就是存文件)反序列化:把字节序列恢复为对象的过程称为对象阿德反序列化。2.序列化和反序列化的使用:java.io.ObjectOutputStream...

    1.序列化和反序列化

    序列化:把对象转换为字节序列的过程称为对象的序列化。(常见的就是存文件)

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

    2.序列化和反序列化的使用:

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

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

    只有实现了Serializable或Externalizable接口的类的对象才能被序列化。

    关于接口 Serializable的描述:

    类通过实现 java.io.Serializable 接口以启用其序列化功能。

    未实现此接口的类将无法使其任何状态序列化或反序列化。

    可序列化类的所有子类型本身都是可序列化的。因为实现接口也是间接的等同于继承。

    序列化接口没有方法或字段,仅用于标识可序列化的语义。

    对象序列化包括如下步骤:

    1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

    2) 通过对象输出流的writeObject()方法写对象。

    对象反序列化的步骤如下:

    1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

    2) 通过对象输入流的readObject()方法读取对象。

    代码:

    ObjectOutputStream代表对象输出流:

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

    ObjectInputStream代表对象输入流:

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

    定义Person类,实现Serializable接口

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    importjava.io.Serializable;

    public class Demo1Person implementsSerializable{

    publicString name;

    //禁止组织成员变量序列化 transient (public  transient int  age;)

    public intage;

    publicString getName() {

    returnname;

    }

    public voidsetName(String name) {

    this.name =name;

    }

    public intgetAge() {

    returnage;

    }

    public void setAge(intage) {

    this.age =age;

    }

    public Demo1Person(String name, intage) {

    super();

    this.name =name;

    this.age =age;

    }

    @Override

    publicString toString() {

    return "Demo1Person [name=" + name + ", age=" + age + "]";

    }

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    序列化和反序列化Person对象

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    importjava.io.FileInputStream;

    importjava.io.FileOutputStream;

    importjava.io.ObjectInputStream;

    importjava.io.ObjectOutputStream;

    //IO流的对象 实现对IO流的序列化和反序列化

    public classDemo1ObjectStream {

    public static void main(String[] args) throwsException {

    //writeObject();

    readObject();

    }

    public static void writeObject() throwsException{

    FileOutputStream fos=new FileOutputStream("c:\\person.txt");

    //创建写出对象的序列化流的对象,构造方法传递字节输出流,writeObject()写对象

    ObjectOutputStream oos=newObjectOutputStream(fos);

    Demo1Person p=new Demo1Person("光头强", 5);

    oos.writeObject(p);

    oos.close();

    }

    public static void readObject() throwsException{

    FileInputStream fis=new FileInputStream("c:\\person.txt");

    //创建反序列化流,readObject()读对象

    ObjectInputStream ois=newObjectInputStream(fis);

    Object obj=ois.readObject();//读对象

    System.out.println(obj);

    ois.close();

    }

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    展开全文
  • 序列化与反序列化的含义:1、Java序列化是指把Java对象转换为字节序列的过程;2、Java反序列化是指把字节序列恢复为Java对象的过程二. 序列化与反序列化的目的:将Java 对象变成二进制字节,以便在两个进程中通信或...

    一. 序列化与反序列化的含义:

    1、Java序列化是指把Java对象转换为字节序列的过程;

    2、Java反序列化是指把字节序列恢复为Java对象的过程

    二. 序列化与反序列化的目的:

    将Java 对象变成二进制字节,以便在两个进程中通信或传输,提高通信效率,实现数据的持久化

    三.JDK 中序列化相关的类:

    1. java.io.ObjectOutputStream:表示对象输出流

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

    2.java.io.ObjectInputStream:表示对象输入流

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

    只有实现了Serializable或Externalizable接口的类的对象才能被序列化,否则抛出异常

    四.在JDK类库中序列化的步骤:

    1.创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流:

    ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream(“D:\\objectfile.obj”));

    2.通过对象输出流的writeObject()方法写对象:

    out.writeObject(“Hello”);

    out.writeObject(new Date());

    五.JDK类库中反序列化的步骤

    1.创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流:

    ObjectInputStream in = new ObjectInputStream(new fileInputStream(“D:\\objectfile.obj”));

    2.通过对象输出流的readObject()方法读取对象:

    String obj1 = (String)in.readObject();

    Date obj2 = (Date)in.readObject();

    注意:为了正确读取数据,完成反序列化,必须保证向对象输出流写对象的顺序与从对象输入流中读对象的顺序一致。

    展开全文
  • using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; namespace Common { /// <summary>... /// XML序列化与反序列化 /// </summary> publi...
    using System.IO;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    
    namespace Common {
        /// <summary>
        /// XML序列化与反序列化
        /// </summary>
        public static class XmlSerializeUtil {
            private static XmlSerializerNamespaces _namespaces;
            private static XmlWriterSettings _settings;
    
            /// <summary>
            /// 静态构造函数,应用程序生命周期内只执行一次
            /// </summary>
            static XmlSerializeUtil() {
                _settings = new XmlWriterSettings {
                    Indent = true,
                    IndentChars = "\t",
                    Encoding = Encoding.UTF8,
                };
                _namespaces = new XmlSerializerNamespaces();
                _namespaces.Add("", "");
            }
    
            /// <summary>
            /// XML反序列化为对象
            /// </summary>
            /// <typeparam name="T">类型</typeparam>
            /// <param name="xml">xml字符串</param>
            /// <returns>T</returns>
            public static T Deserialize<T>(string xml) where T : class {
                using (var sr = new StringReader(xml)) {
                    var serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(sr) as T;
                }
            }
            /// <summary>
            /// XML反序列化为对象
            /// </summary>
            /// <typeparam name="T">类型</typeparam>
            /// <param name="xml">xml</param>
            /// <returns>T</returns>
            public static T Deserialize<T>(Stream xml) where T : class {
                var serializer = new XmlSerializer(typeof(T));
                return serializer.Deserialize(xml) as T;
            }
    
            /// <summary>
            /// 对象序列化为XML字符串
            /// </summary>
            /// <typeparam name="T">类型</typeparam>
            /// <param name="data">数据</param>
            /// <returns>XML字符串</returns>
            public static string Serializer<T>(T data) {
                var serializer = new XmlSerializer(typeof(T));
    
                using (var stream = new MemoryStream())
                using (var reader = new StreamReader(stream))
                using (var writer = XmlWriter.Create(stream, _settings)) {
                    serializer.Serialize(writer, data, _namespaces);
                    
                    stream.Position = 0;
    
                    return reader.ReadToEnd();
                }
            }
        }
    }

     

    转载于:https://www.cnblogs.com/quxian/p/8418300.html

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

    2019-01-23 02:06:32
    序列化与反序列化是一个标准(具体参考XDR:外部数据表示标准 RFC 1014),它是编程语言的一种共性,只是有些编程语言是内置的(如Java,PHP等),有些语言是通过第三方库来实现的(如C/C++)。 使用场景 对象的持久...

    序列化与反序列化是开发过程中不可或缺的一步,简单来说,序列化是将对象转换成字节流的过程,而反序列化的是将字节流恢复成对象的过程。两者的关系如下:

    序列化与反序列化是一个标准(具体参考XDR:外部数据表示标准 RFC 1014),它是编程语言的一种共性,只是有些编程语言是内置的(如Java,PHP等),有些语言是通过第三方库来实现的(如C/C++)。

    使用场景

    • 对象的持久化(将对象内容保存到数据库或文件中)
    • 远程数据传输(将对象发送给其他计算机系统)

    为什么需要序列化与序列化?

    序列化与序列化主要解决的是数据的一致性问题。简单来说,就是输入数据与输出数据是一样的。

    对于数据的本地持久化,只需要将数据转换为字符串进行保存即可是实现,但对于远程的数据传输,由于操作系统,硬件等差异,会出现内存大小端,内存对齐等问题,导致接收端无法正确解析数据,为了解决这种问题,Sun Microsystems在20世纪80年代提出了XDR规范,于1995年正式成为IETF标准。

    Java中的序列化与反序列化

    Java语言内置了序列化和反序列化,通过Serializable接口实现。

    public class Account implements Serializable {
    
    	private int age;
    	private long birthday;
    	private String name;
    }
    复制代码

    序列化兼容性

    序列化的兼容性指的是对象的结构变化(如增删字段,修改字段,字段修饰符的改变等)对序列化的影响。为了能够识别对象结构的变化,Serializable使用serialVersionUID字段来标识对象的结构。默认情况下,它会根据对象的数据结构自动生成,结构发生变化后,它的值也会跟随变化。虚拟机在反序列化的时候会检查serialVersionUID的值,如果字节码中的serialVersionUID和要被转换的类型的serialVersionUID不一致,就无法进行正常的反序列化。

    示例:将Account对象保存到文件中,然后在Account类中添加address字段,再从文件中读取之前保存的内容。

    // 将Account对象保存到文件中
    FileOutputStream fos = new FileOutputStream(file);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(account);
    oos.flush();
    
    // 修改Account对象的结构
    public class Account implements Serializable {
    
    	private int age;
    	private long birthday;
    	private String name;
    	private String address;
    	
    	public Account(int age, String name) {
    	    this.age = age;
    	    this.name = name;
    	}
    }   
    
    // 读取Account的内容
    FileInputStream fis = new FileInputStream(file);
    ObjectInputStream ois = new ObjectInputStream(fis);
    Account account2 = (Account)ois.readObject();
    复制代码

    由于在保存Account对象后修改了Account的结构,会导致serialVersionUID的值发生变化,在读文件(反序列化)的时候就会出错。所以为了更好的兼容性,在序列化的时候,最好将serialVersionUID的值设置为固定的。

    public class Account implements Serializable {
    
        private static final long serialVersionUID = 1L;
        
        private int age;
        private long birthday;
        private String name;
    }
    复制代码

    序列化的存储规则

    Java中的序列化在将对象持久化(序列化)的时候,为了节省磁盘空间,对于相同的对象会进行优化。当多次保存相同的对象时,其实保存的只是第一个对象的引用。

    // 将account对象保存两次,第二次保存时修改其用户名
    Account account = new Account("Freeman");
    FileOutputStream fos = new FileOutputStream(file);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(account);
    System.out.println("fileSize=" +file.length());
    account.setUserName("Tom");
    oos.writeObject(account);
    System.out.println("fileSize=" +file.length());
    
    // 读取两次保存的account对象
    FileInputStream fis = new FileInputStream(file);
    ObjectInputStream ois = new ObjectInputStream(fis);
    Account account2 = (Account)ois.readObject();
    Account account3 = (Account)ois.readObject();
    System.out.println("account2.name=" + account2.getUserName() + "\n  account3.name=" + account3.getUserName() + "\naccount2==account3 -> " + account2.equals(account3));
    复制代码

    输出结果:

    account2.name=Freeman  
    account3.name=Freeman 
    account2==account3 -> true
    复制代码

    所以在对同一个对象进行多次序列化的时候,最好通过clone一个新的对象再进行序列化。

    序列化对单例的影响

    反序列化的时候,JVM会根据序列化生成的内容构造新的对象,对于实现了Serializable的单例类来说,这相当于开放了构造方法。为了保证单例类实例的唯一性,我们需要重写resolveObject方法。

    /**
     * 在反序列化的时候被调用
     * @return 返回根据字节码创建的新对象
     * @throws ObjectStreamException
     */
    private Object readResolve()throws ObjectStreamException {
        return instance;
    }
    复制代码

    控制序列化过程

    虽然直接使用Serializable很方便,但有时我们并不想序列化所有的字段,如标识选中状态的isSelected字段,涉及安全问题的password字段等。此时可通过通过以下方法实现:

    1. 给不想序列化的字段添加static或transient修饰词:

    Java中的序列化保存的只是对象的成员变量,既不包括static成员(static成员属于类),也不包括成员方法。同时Java为了让序列化更灵活,提供了transient关键字,用来关闭字段的序列化。

    public class Account implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private String userName;
        private static String idcard;
        private transient String password;
    }
    复制代码
    1. 直接使用Externalizable接口控制序列化过程:

    Externalizable也是Java提供的序列化接口,与Serializable不同的是,默认情况下,它不会序列化任何成员变量,所有的序列化,反序列化工作都需要手动完成。

    public class Account implements Externalizable {
    
        private static final long serialVersionUID = 1L;
        
    	private String userName;
    	private String idcard;
    	private String password;
    	
    	@Override
    	public void writeExternal(ObjectOutput out) throws IOException {
    		out.writeObject(userName);
    	}
    	
    	@Override
    	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    		userName = (String) in.readObject();
    	}
    }
    复制代码
    1. 自己实现序列化/反序列化过程

      public class Account implements Serializable {

       private static final long serialVersionUID = 1L;
       
       private String userName;
       private transient String idcard;
       private String password;
       
       private void writeObject(ObjectOutputStream oos)throws IOException {
       	// 调用默认的序列化方法,序列化非transient/static字段
       	oos.defaultWriteObject();
       	oos.writeObject(idcard);
       }
       
       private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
       	// 调用默认的反序列化方法,发序列化非transient/static字段
       	ois.defaultReadObject();
       	idcard = (String)ois.readObject();
       }
      复制代码

      }

    关于Java序列化算法的详细介绍可参考:Java序列化算法透析

    Java序列化注意事项

    1. 通过Serializable序列化的对象,在反序列化的时候,直接根据字节码构造对象,并不会调用对象的构造方法;
    2. 通过Serializable序列化子类时,如果父类没有实现Serializable接口,那么父类需要提供默认的构造方法,否则在反序列化的时候抛出java.io.NotSerializableException异常;
    3. 通过Externalizale实现序列化时,反序列化的时候需要调用对象的默认构造方法;
    4. 由于Externalizale默认情况下不会对任何成员变量进行序列化,所以transient关键字只能在Serializable序列化方式中使用;

    数据交换协议

    序列化与反序列化为数据交换提供了可能,但是因为传递的是字节码,可读性差。在应用层开发过程中不易调试,为了解决这种问题,最直接的想法就是将对象的内容转换为字符串的形式进行传递。具体的传输格式可自行定义,但自定义格式有一个很大的问题——兼容性,如果引入其他系统的模块,就需要对数据格式进行转换,维护其他的系统时,还要先了解一下它的序列化方式。为了统一数据传输的格式,出现了几种数据交换协议,如:JSON, Protobuf,XML。这些数据交换协议可视为是应用层面的序列化/反序列化。

    JSON

    JSON(JavaScript Object Notation)是一种轻量级,完全独立于语言的数据交换格式。目前被广泛应用在前后端的数据交互中。

    语法

    JSON中的元素都是键值对——key:value形式,键值对之间以":"分隔,每个键需用双引号引起来,值的类型为String时也需要双引号。其中value的类型包括:对象,数组,值,每种类型具有不同的语法表示。

    对象

    对象是一个无序的键值对集合。以"{"开始,以"}"结束, 每个成员以","分隔。例如:

    "value" : {
        "name": "Freeman",
        "gender": 1
    }
    复制代码
    数组

    数组是一个有序的集合,以"["开始,以"]"结束,成员之间以","分隔。例如:

    "value" : [
        {
            "name": "zhangsan",
            "gender": 1
        },
        {
            "name": "lisi",
            "gender": 2
        }
    ]
    复制代码

    值类型表示JSON中的基本类型,包括String,Number(byte, short, int, long, float, double), boolean。

    "name": "Freeman"
    "gender": 1
    "registered": false
    "article": null
    复制代码

    ==注意==:对象,数组,值这三种元素可互相嵌套!

    {
        "code": 1,
        "msg": "success",
        "data": [
            {
                "name": "zhangsan",
                "gender": 1
            },
            {
                "name": "lisi",
                "gender": 2
            }
        ]
    }
    复制代码

    对于JSON,目前流行的第三方库有Gson, fastjson:关于Gson的详细介绍,参考Gson使用教程

    Protobuf

    Protobuf是Google实现的一种与语言无关,与平台无关,可扩展的序列化方式,比XML更小,更快,使用更简单。

    Protobuf具有很高的效率,并且几乎为主流的开发语言都提供了支持,具体参考Protobuf开发文档

    在Android中使用Protobuf,需要protobuf-gradle-plugin插件,具体使用查看其项目说明。

    XML

    XML(Extensible Markup Language)可扩展标记语言,通过标签描述数据。示例如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <person>
        <name>Freeman</name>
        <gender>1</gender>
    </person>
    复制代码

    使用这种方式传输数据时,只需要将对象转换成这种标签形式,在接收到数据后,将其转换成相应的对象。

    关于JAVA开发中对XML的解析可参考四种生成和解析XML文档的方法详解

    数据交换协议如何选择

    从性能,数据大小,可读性三方面进行比较,结果如下:

    协议 性能 数据大小 可读性
    JSON
    Protobuf
    XML

    对于数据量不是很大,实时性不是特别高的交互,JSON完全可以满足要求,毕竟它的可读性高,出现问题容易定位(注:它是目前前端,app和后端交换数据使用的主流协议)。而对于实时性要求很高,或数据量大的场景,可使用Protobuf协议。具体数据交换协议的比较可参考github.com/eishay/jvm-…

    展开全文
  • 序列化与反序列化 C/C++中实现手工序列化 调用MFC框架实现序列化和反序列化
  • struct2json:JSON和C结构之间的快速转换库。 为C实现结构序列化和反序列化C结构体JSON快速互转库,快速实现C结构体的序列化及反序列化
  • 序列化与反序列化***为什么要序列化 ?定义pickle库#序列化实例importpicklelst= 'a b c'.split()with open('test.txt','wb+')as f:pickle.dump(lst,f)file= 'test.txt'with open(file,'wb')as f:s1= 99s2= 'abc's3=...
  • 序列化和反列序列化序列化与反序列化的内容写对象叫序列化,读对象叫反序列化序列化保存的元素a) 只能保存对象的非静态成员变量b) 不能保存任何成员方法和静态的成员变量c) 不保存transient成员变量d) 如果保存一个...
  • C/C++序列化与反序列化-深入理解

    万次阅读 2018-08-26 14:07:58
    反序列化就是将字节数据还原成内存对象。 如: struct student { int id; string name; }; 将一个student对象转换成字节数据存储在ByteArray[20]中称为序列化代码如 int count = 0; char ByteAr...
  • java序列化与反序列化

    2017-02-17 13:32:48
    把Student类的对象序列化到文件O:\\Java\\com\\jieke\\io\\student.txt,并从该文件中反序列化,向console显示结果... *Description:实现学生类实例的序列化与反序列化 *Copyright: copyright(c) 2012 *Filename: Us
  • 反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性。1. serialize和unserialize函数这两个是序列化和反序列化PHP中数据的常用函数。...
  • 遇到这个 Java Serializable 序列化这个接口,我们可能会有如下的问题a,什么叫序列化和反序列化 b,作用。为啥要实现这个 Serializable 接口,也就是为啥要序列化 c,serialVersionUID 这个的值到底是在怎么设置的...
  • a,什么叫序列化和反序列化 b,作用。为啥要实现这个 Serializable 接口,也就是为啥要序列化 c,serialVersionUID 这个的值到底是在怎么设置的,有什么用。有的是1L,有的是一长串数字,迷惑ing。 我刚...
  • 分享套接字数据包序列化与反序列化方法“简单说一下,本文不涉及Socket的连接、数据接收,只是对数据包(byte[])的序列化和反序列化方法的封装介绍。本文目录本文背景一般操作本文操作总结1.本文背景经常做C/S,...
  • 但是,今天我忍不住点开了,一看,二叉树的序列化与反序列化,这个东东是啥啊。二叉树,我学过哎,我可以。 然后看了下,发现 二叉树的序列化就是:将一颗二叉树,转换成一维的序列。 二叉树的反序列化就是:从一维...
  • php序列化与反序列化

    2020-09-27 17:08:01
    序列化: 举个简单的例子: <?php class Test{ protected $a=1; private $b=1; public $c=1; } $test=new Test(); $a=serialize($test); echo $a; ?> 输出: O表示类型是object 4表示object对应的类的...
  • RestController ResponseBody 底层是用的jackson json来序列化与反序列化 http接口都是json格式的序列化 jackson序列化注意点: 被 序列化/反序列化 的实体 a. 必须要有无参构造方法 b.字段要有set/get方法 c. 不...
  • xml序列化与反序列化

    2015-07-10 09:56:00
    一、使用VS2013生成类 首先使用ctr+c拷贝要序列化的xml(这一步必须做) 二、使用vs生成类 1、 首先新建一个空的类(根据需要去设置类名) 2、 ... /// xml序列化和反序列化 /// </summa...
  • 二叉树的序列化与反序列化 本题思路: 所谓序列化,就是把树结构变成链状结构,也就是在考察二叉树的遍历方式 /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode ...
  • 分享套接字数据包序列化与反序列化方法“ 简单说一下,本文不涉及Socket的连接、数据接收,只是对数据包(byte[])的序列化和反序列化方法的封装介绍。本文目录本文背景一般操作本文操作总结1.本文背景经常做C/S,...
  • Java对象的序列化与反序列化 原文链接:https://mp.weixin.qq.com/s?__biz=MzI3NzE0NjcwMg==&mid=2650120836&idx=1&sn=c83a980c0871faf607ae613092c69760&chksm=f36bbfa5c41c36b317c103f27b9d99c26...
  • 简单来说,由于列表或者字典不能直接保存在文件中,需要将其序列化为字符串后保存,然后使用时从文件中反序列化获取列表或者字典。 #!/usr/bin/env python#_*_coding:utf-8_*_import pickleli = ['a', 'b', 'c']...
  • } 1.2 从文件读取数据,并序列化成json读出 int read_json_info(void) { FILE* file = fopen("/tmp/json_data","r"); if(file == NULL){ printf("open failed\n"); return -1; } fseek(file,0,SEEK_END); int len=...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 413
精华内容 165
关键字:

c序列化与反序列化