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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:10043---java动态代理(cglib)
下一篇:10041---打印流,数据流

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2024年04月21日 12时31分36秒