首页 > 知识库 > 正文

Java序列化,怎么把一个类,序列化到一个文件中去?

在2113java中只要一个类实现了Serializable接口5261的类就被认为是序列化的类,这种类的4102对象就是序列化的对象只有被序1653列化的数据才允许被存储到文件、数据库之中或者通过网络协议进行传输,没有被序列化的数据是不能存储到硬盘上,不能通过网络协议进行网络传输,序  列 化:  指把堆内存中的Java对象2113数据,通过某种方式把对象存储到5261磁盘文件中或者传递给其他网络4102的节点(在网络上传输).我们把这个过程称之为序列化.反序列化:把磁盘文件中的对1653象数据或者把网络节点上的对象数据,恢复成Java对象的过程.为什么要做序列化:1):在分布式系统中,需要共享的数据的JavaBean对象,都得做序列化,此时需要把对象再网络上传输,此时就得把对象数据转换为二进制形式.以后存储在HttpSession中的对象,都应该实现序列化接口(只有实现序列化接口的类,才能做序列化操作).2):服务钝化:如果服务发现某些对象好久都没有活动了,此时服务器就会把这些内存中的对象,持久化在本地磁盘文件中(Java对象-->二进制文件).如果某些对象需要活动的时候,现在内存中去寻找,找到就使用,找不到再去磁盘文件中,反序列化我们得对象数据,恢复成Java对象.需要做序列化的对象的类,必须实现序列化接口:java.io.Serializable接口(标志接口[没有抽象方法]).底层会判断,如果当前对象是Serializable的实例,才允许做序列化.    boolean   ret = Java对象  instanceof  Serializable;在Java中大多数类都已经实现Serializable接口www.shufadashi.com防采集。

实习序列号接口,再使用objecOutputStream持久化到磁盘文件中。哎,好低级的问题,io重修吧。

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。 序列化的实现:将需要被序列化的类

楼主的问题很有意思,不过2113你对序列化和5261反序列的应用场景搞错了,我们说的序列4102化和反序列1653化是对JAVA而言(其他面向对象语言可能也有)的,序列化的实体是个对象,结果也是个对象,并非是格式化文本,你在记事本里看到的购物信息保存记录,其实不是对象序列化的结果,而是对象输出的格式化文本,真正的序列化对象是看不懂的。在实际使用对象序列化时,一种应用场景是将对象序列化到持久化存储(本地硬盘),我们此时不想做文件解析,也不想有人读懂这个持久化文件,当我们需要时,可以直接采用反序列化将保存的文件生成为对象;另一种应用场景是在网络传输过程中,此时对象会在不同主机上传播,序列化会将对象转成码流由对端进行解析,这个解析过程不需要人参与。普通字符串是经过解析后的对象,有对象到字符串要加入解析逻辑,人才能看懂。序列化的结果是个只有JAVA虚拟机认识的文件,人不参与,只是用于保存对象或传输。解决你的问题了么?更多追问追答追问序列化和购物信息记录里的字符串有关系吗?比如我不序列化,这些字就不能保存到硬盘了吗?还一个就是序列化以后保存的对象在哪里啊,是购物信息记录里面的文字吗?都一起保存到硬盘上面了?还是放哪里,比如我打开购物信息记录里面只有:某某于某天购物等等,这里面哪有对象啊,跟看文本文件没区别啊,那咱们老说保存对象对象的 我不明白这个对象到底在哪里,和字符串有什么关系没追答序列化和字符串没有关系。字符串是对象里的某些数据的输出结果,你看到的文本文件只包含了对象的一部分信息,你看到可能只是个值而已。比如一个对象object monkey{ String monkeyName = "悟空"; long monkeyAge = 1000;}你输出的字符串可能只是这个:悟空;10000;但对象很多信息丢掉了,比如对象名称,字段属性之类的。序列化时把对象完整的输入到某个地方,比如文件,这个文件人类是看不懂的,但在反序列化时,文件就会被完成的读取为一个对象,和上面的对象一模一样,这样我们就可以在代码中对对象进行直接操作了。are we clear?追问good!,原来如此,但是另一个问题又来了,对象保存在哪里?是跟我的文本文件一起保存到硬盘里吗?比如我的文本里字符串是5个字符串文字,按一个字符是2字节,大小是10字节,那如果按你的说法,把字段 名称也保持了,那文件的内容会增多,那有可能不是10字节了,因为你还保存了字段 属性名什么的,那岂不是多占我硬盘空间了?追答保存在哪里是你控制的,你想输出到文件系统也可以,其他地方也行。你说的大小我不知道跟什么比较,一般情况下肯定会比只保存字符串要大,毕竟有其他的信息需要存储。会多占你些空间,但比起你手动反序列化这些成本还是值得的。追问我的意思是说,你序列化以后保存的对象内容,是不是也在最终产生的文本文件里?比如生成了一个购物信息记录.txt的文件,这里面假如有购物信息这4个文字,那对象能在文本里看到吗?还是只能看到字符串?保存的对象其实也在这个文件里,但是不会输出显示,而且最重要的是文件的大小在电脑里还是显示4个字符的大小,但是对象它也是存在的也占硬盘空间,只不过系统只显示字符串的大小而已?追答文本文件是用来保存文本的,是你在代码里控制生成txt。对象序列化生成的序列化文件,跟txt文件没有关系,你序列化之后存成什么样的文件格式,存储到什么位置,是自己控制的。你不应该认为txt存储对象,txt存储的只能是文本,对象序列化的结果是一个序列化文件,是一个文件输出流的结果。追问序列化文件保存在哪,我想见识见识,保存在电脑的哪个角落里?我看看跟文本文件有啥不一样的追答import java.io.Serializable;import java.io.*;public class Cat implements Serializable {private String name;public Cat() {this.name = "new cat";}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public static void main(String[] args) {Cat cat = new Cat();try {FileOutputStream fos = new FileOutputStream("catDemo.out"); //这就是你序列化文件的存储位置,是由自己控制的ObjectOutputStream oos = new ObjectOutputStream(fos);System.out.println(" 1> " + cat.getName());cat.setName("My Cat");oos.writeObject(cat);oos.close();}catch (Exception ex) {ex.printStackTrace();}try {FileInputStream fis = new FileInputStream("catDemo.out");ObjectInputStream ois = new ObjectInputStream(fis);cat = (Cat) ois.readObject();System.out.println(" 2> " + cat.getName());ois.close();}catch (Exception ex) {ex.printStackTrace();}}}输出内容:追问原来.out文件就是序列化后的文件啊,那保存的购物信息记录也全在这里面吗?如果是在这里,那这个文件不是.txt格式的,打开看肯定是乱码?如果信息记录没在out文件里,那应该在指定一个路径保存为.txt文件格式吧?这个就是能打开看的信息记录?这俩文件是分开的 还是合在一起的?追答保存的购物信息都在catDemo.out中,但你是看不懂的,要JAVA虚拟机才能看懂,因为序列化文件本身不是为人类阅读准备的。如果你想输出为txt,需要你在程序中手动指定输出的内容和格式,这样你才能够看懂。不是两个文件,也可能是多个文件,你想生成多少文件就生成多少文件。追问那在问下,如果我也想保存输出为txt格式的。在程序中手动添加一个路径为:购物信息.txt就行了是吗?那你上面的那个catDemo.out不用删掉继续保留?这样在电脑里就会产生一个是catDemo.out文件,一个是文本格式的购物信息.txt?catDemo.out已经是序列化保存了一次了,后面再输出的.txt不需要序列化了,直接输出字符流保存到电脑里即可?因为前面已经有一个序列化了追答对的,你可以这样理解。另外你是否需要序列化看你自己的需求,序列化是为了程序读取方便,没有必要非得输出的。追问意思就是说,你要不序列化也行,就是程序读取不方便,而且以前在内存里的对象结构全都没有了?上面那个还要问下,其实在catDemo.out文件里只包含对象信息,应该也包含字符串信息吧?就是应该也包含txt里面的购物信息,而我输出txt格式,只是从catDemo.out文件里提取出字符串部分的信息给用户看而已,实际对象内容还在catDemo.out里保存?追答序列化是一种操作,你做序列化不是必要的,你做序列化是因为你想保存这个对象在文件系统上。想象一种场景:你开发了一个游戏,游戏里有人物,人物里有个属性时他现在拥有的金钱,当用户玩到一半选择保存游戏时,你有两个方案:保存用户的金钱到txt中,下次加载游戏的时候,再从txt中读取金钱,让用户接着玩。进行对象序列化,把对象存到文件系统上,下次可以玩的时候使用反序列化加载。但是第一种方案有个缺点,用户如果知道了txt中保存着金钱,就可以自己把金钱改成99999,采用对象序列化方式就不会了。最后一个,你没有理解JAVA中的对象,对象是在内存中保存的,它不会因为你序列化了之后它就不存在了,序列化等于把对象的数据复制了一份,序列化,然后输出到文件系统,真正的对象还是在程序中的。就像你玩游戏玩到一半,突然想存个档,然后就把对象序列化了,但是游戏还在继续啊,里面的人物也没死啊,说明人这个对象还是在内存中存在的。are we clear?,序列2113化就是将一个对象的状态(各个属性量)保5261存起来,然后在适当4102的时候再获得。  序列化1653分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例  序列化的什么特点:  如果某个类能够被序列化,其子类也可以被序列化。声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态, transient代表对象的临时数据。  什么时候使用序列化:  一:对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。  二:java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列,要使得javabean能够通过2113I/O在网络传输那么就必须实现5261Serializable接口,这是4102一种规范,就相当于你要tomcat调用1653你的servlet你必须实现它的接口一样。要解释你的疑问就说说流吧:首先流分为:字节流(Inputstream)、字符流(Reader),而你说的文件那就属于FileInputStream属于字节流,而你说的对象那就是ObjectInputStream也属于字节流,但是写对象必须实现Serializabled接口(这是API文档原话:只能将支持 java.io.Serializable 接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。)追问FileInputStream属于字节流,这也是字节流,是不是说如果我保存的不是对象,可以用这个流?可是java里好像都有对象啊,那就都只能用ObjectInputStream流?那保存的购物记录是文本文件啊,打开能看到里面的文字信息,也没看到有对象啊,那序列化保存的对象在哪里啊,也在购物记录里吗,一起保存到硬盘里去了?追答文本文件属于字符流(Reader),让你看下API文档原话你就明白了:FileReader 用于读取字符流。要读取原始字节流,请考虑使用 FileInputStream。 大哥还在纠结啊。。。 我最后就给你讲一个大家熟悉的一个例子大家都用过web容器吧,现在就说weblogic假如我们要去注册帐号,我们是先进入注册页面,把必填的都填完,最后点击注册按钮ok此时客户端就发送了一个request注册的请求,1客户端先把用户填写的信息保存在该请求中-------------------------------客户端2然后把该请求request对象序列化,request对象保存了用户填写的注册信息Socket socket=new Socket("ip",10000); ObjectOutputStream oos1 = new ObjectOutputStream(socket.getOutputStream());FileOutputStream out = new FileOutputStream("file.object"); //楼主看看跟文本文件有啥不一样的ObjectOutputStream oos2 = new ObjectOutputStream(out);oos1.writeObject(request); //楼主要看序列化是怎么样的加这句oos2.writeObject(request);oos.close();3然后服务器也就是weblogic接收该请求,进行反序列化-----------------------------服务器ServerSocket ss=new ServerSocket(10000); while(true){ socket=ss.accept(); ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); Request request= (Request) ois.readObject(); ois.close();} 写的好累啊。。。望楼主采纳!!!,以前我也不理解,不过现在2113我已经理解了5261:是这样的,如果JAVA的对4102象要保存到硬盘或者要传输,必须实现Serializable接口,则这1653个接口,里面什么方法都没,它只是一个标识,而且,最好有一个序列的版本号,如private static final long serialVersionUID = 1L;以前我做过实验,我写了一个类Person,然后Person p=new Person();通过序列化,我用代码把p这个对象,保存在文件文件里了!不序列化,绝对不可能保存在计算机硬盘里!追问那文本文件打开后是不是只能看到字符串,看不见保存的对象信息?但是这个文件里面确实有对象信息,只不过系统不给你显示出来,只显示字符串内容而已?而且这个文件实际大小应该是字符串大小+对象大小,但是系统一样只显示文本信息的字符串大小?是这么理解吧?追答我用代码把p这个对象,保存在文件文件里后,打开看了,不像乱码,但又像乱码的东西。你说得对,只能看到字符串,看不见保存的对象信息,但,你用代码处理后,就可以看见保存的对象信息了。要自己写代码处理,当初怎么写,就反过来,就可以显示对象的信息了。大小与你的对象个数有关,我那时也做了试验,我循环写10与10000次,大小就不一样了。文件大小,不好说,应该只与对象有关,哪来的什么字符串。代码是别人帮我写字,但忘记在哪了,不然,贴出来给你,你就理解了,你知道什么叫 序列化2113 吗? 你知5261道序列化4102的作用吗?你可以把序列化,实现Serializable 接口,是序列化了的类告1653知该程序,这个类的对象可以读写。读写不仅仅是在文本中读写该类,还可以通过别的流来进行读写。没有序列化的类,是不能形成二进制读写流。如果你随便敲写文字进去一个记事本里面。这个就不是序列化的范围了。序列化是指类对象的。你能确保你自己敲上去的文字就是类的对象了吗?你能确保你敲上去的是什么类的对象吗?第三个问题,已经没有必要解释了。你要知道序列化是什么东西,你就不会问这问题本回答被网友采纳内容来自www.shufadashi.com请勿采集。

声明:本网内容旨在传播知识仅供参考,不代表本网赞同其观点,文字及图片版权归原网站所有。

你可能还关注
热门推荐
今日推荐 更多