10042---对象流和RandomAccessFile
发布日期:2021-06-28 19:53:37
浏览次数:2
分类:技术文章
本文共 6061 字,大约阅读时间需要 20 分钟。
ObjectInputStream和 OjbectOutputSteam 用于存储和读取对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。 序列化( Serialize):用 ObjectOutputStream类将一个Java对象写入IO流中 反序列化( Deserialize):用ObjectInputStream类从IO流中恢复该Java对象ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
对象的序列化
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象
序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原 序列化是 RMI(Remote Method Invoke – 远程方法调用)过程的参数和返回值都必须实现的机制,而 RMI 是 JavaEE 的基础。因此序列化机制是 JavaEE 平台的基础 如果需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一: Serializable Externalizable--
凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:
private static final long serialVersionUID; serialVersionUID用来表明类的不同版本间的兼容性 如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的源代码作了修改,serialVersionUID 可能发生变化。故建议,显示声明, 显示定义serialVersionUID的用途 希望类的不同版本对序列化兼容,因此需确保类的不同版本具有相同的serialVersionUID 不希望类的不同版本对序列化兼容,因此需确保类的不同版本具有不同的serialVersionUID使用对象流序列化对象
若某个类实现了 Serializable 接口,该类的对象就是可序列化的: 创建一个 ObjectOutputStream 调用 ObjectOutputStream 对象的 writeObject(对象) 方法输出可序列化对象。注意写出一次,操作flush() 反序列化 创建一个 ObjectInputStream 调用 readObject() 方法读取流中的对象 强调:如果某个类的字段不是基本数据类型或 String 类型,而是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的 Field 的类也不能序列化.
序列化:将对象写入到磁盘或者进行网络传输。
// 对象的反序列化过程:将硬盘中的文件通过ObjectInputStream转换为相应的对象 @Test public void testObjectInputStream() { ObjectInputStream ois = null; try { ois = new ObjectInputStream(new FileInputStream( "person.txt")); Person p1 = (Person)ois.readObject(); System.out.println(p1); Person p2 = (Person)ois.readObject(); System.out.println(p2); }catch (Exception e) { e.printStackTrace(); }finally{ if(ois != null){ try { ois.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } // 对象的序列化过程:将内存中的对象通过ObjectOutputStream转换为二进制流,存储在硬盘文件中 @Test public void testObjectOutputStream() { Person p1 = new Person("小米", 23,new Pet("花花")); Person p2 = new Person("红米", 21,new Pet("小花")); ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new FileOutputStream("person.txt")); oos.writeObject(p1); oos.flush(); oos.writeObject(p2); oos.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (oos != null) { try { oos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }}/* * 要实现序列化的类: 1.要求此类是可序列化的:实现Serializable接口 * 2.要求类的属性同样的要实现Serializable接口 * 3.提供一个版本号:private static final long serialVersionUID * 4.使用static或transient修饰的属性,不可实现序列化 */class Person implements Serializable { private static final long serialVersionUID = 23425124521L; static String name; transient Integer age; Pet pet; public Person(String name, Integer age,Pet pet) { this.name = name; this.age = age; this.pet = pet; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", pet=" + pet + "]"; } }class Pet implements Serializable{ String name; public Pet(String name){ this.name = name; } @Override public String toString() { return "Pet [name=" + name + "]"; }
RandomAccessFile类
构造器 public RandomAccessFile(File file, String mode) public RandomAccessFile(String name, String mode) 创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指定 RandomAccessFile 的访问模式: r: 以只读方式打开 rw:打开以便读取和写入 rwd:打开以便读取和写入;同步文件内容的更新 rws:打开以便读取和写入;同步文件内容和元数据的更新/* * RandomAccessFile:支持随机访问 * 1.既可以充当一个输入流,又可以充当一个输出流 * 2.支持从文件的开头读取、写入 * 3.支持从任意位置的读取、写入(插入) */public class TestRandomAccessFile { //相较于test3,更通用 @Test public void test4(){ RandomAccessFile raf = null; try { raf = new RandomAccessFile(new File("hello1.txt"),"rw"); raf.seek(4); byte[] b = new byte[10]; int len; StringBuffer sb = new StringBuffer(); while((len = raf.read(b)) != -1){ sb.append(new String(b,0,len)); } raf.seek(4); raf.write("xy".getBytes()); raf.write(sb.toString().getBytes()); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(raf != null){ try { raf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //实现插入的效果:在d字符后面插入“xy” @Test public void test3(){ RandomAccessFile raf = null; try { raf = new RandomAccessFile(new File("hello1.txt"),"rw"); raf.seek(4); String str = raf.readLine();//efg123456// long l = raf.getFilePointer();// System.out.println(l); raf.seek(4); raf.write("xy".getBytes()); raf.write(str.getBytes()); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(raf != null){ try { raf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //实现的实际上是覆盖的效果 @Test public void test2(){ RandomAccessFile raf = null; try { raf = new RandomAccessFile(new File("hello1.txt"),"rw"); raf.seek(4); raf.write("xy".getBytes()); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(raf != null){ try { raf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //进行文件的读、写 @Test public void test1(){ RandomAccessFile raf1 = null; RandomAccessFile raf2 = null; try { raf1 = new RandomAccessFile(new File("hello.txt"), "r"); raf2 = new RandomAccessFile(new File("hello1.txt"),"rw"); byte[] b = new byte[20]; int len; while((len = raf1.read(b)) != -1){ raf2.write(b, 0, len); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(raf2 != null){ try { raf2.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(raf1 != null){ try { raf1.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }}
转载地址:https://blog.csdn.net/xxxcyzyy/article/details/51591630 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2024年04月21日 12时31分36秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
android设计模式原则,4个改变你编程技能的小技巧,手慢无
2019-04-29
Android跨进程通信导论,全网疯传
2019-04-29
想学IT的必看!我的Android美团求职之路,面试总结
2019-04-29
扫地阿姨看完都学会了!大厂offer手到擒来,经典好文
2019-04-29
推荐程序员面试秘籍!2021年Android面试心得,含泪整理面经
2019-04-29
正式加入阿里巴巴!Android自定义View详解,大厂直通车!
2019-04-29
安卓开发基础面试题,30岁以后搞Android已经没有前途?复习指南
2019-04-29
python调试
2019-04-29
雷电模拟器重置开机密码
2019-04-29
其它安全问题
2019-04-29
SSRF
2019-04-29
python3 语法注意
2019-04-29
C语言复习
2019-04-29
Spring:源码解读Spring IOC原理
2019-04-29
Spring AOP原理分析一次看懂
2019-04-29
Spring AOP的实现原理(二)
2019-04-29
Spring AOP的实现原理(三)
2019-04-29
Spring AOP的实现原理(四)
2019-04-29
Spring AOP的实现原理(五)
2019-04-29
Java动态代理与CGLIB
2019-04-29