Java对象的序列化和反序列化

// 对象的序列化和反序列化
// 对象的序列化是指把对象写到一个输出流中,对象的反序列化是指从一个输入流中读取一个对象,java语言要求实现Serializable接口的类才能被序列或反序列
// JDK类库中如String,包装类,Date类都实现了这个接口
// 执行步骤:
// 1 创建一个对象的输出流,他可以包装一个其他类型的输出流,例如文件输出流,2 通过对象输出流的writeObject()方法写对象
// ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream("D:\\objectFile.obj")); out.writeObject("hello"),out.writeObject(new Date());
// 1 创建一个对象的输入流,他可以包装一个其他类型的输入流,例如文件输入流,2 通过对象输入流的readObject()方法读取对象
// ObjectinputStream out = new ObjectinputStream(new fileinputStream("D:\\objectFile.obj")); String obj1 = (String)out.readObject(),Date obj2 = (Date)out.readObject();
// 为了能读取正确的数据,必须保证对象输出流写对象的顺序与从对象输入流读对象的顺序一致
// 通常对于一些敏感信息,处于安全的原因,应该禁止对这种属性进行序列化,解决办法是把这种属性用transient修饰,
// 如果想进一步控制序列化及反序列化,可以在Customer1类中提供一个readObject()和writeObject()方法,当ObjectOutputStream对一个对象进行序列化,如果该对象有writeObject方法,那么就会执行这一方法,没有则按照默认方式序列化
// 在writeObject方法中可以调用ObjectOutputStream的defaultWriteObject方法,使得对象输出流执行默认序列化操作,readObject也是如此
// 以下在writeObject方法中,先对name进行序列化,接着把password属性加密后再序列化,具体办法为获得passwd属性的字节数组,把数组的每个字节的二进制位取反,再把取反后的字节数组写到对象输出流中
// 在Customer1对象的序列化数据中,保存了password属性的加密数据,在反序列化过程中,会把password的加密数据再恢复为password属性
// 值得注意的是readObject方法和writeObject方法并不是在Serializable接口中定义的,JDK类库的设计人员没有把这两个方法放在Serializable接口中,优点在于:
// 不必公开这两个方法的访问权限,以便封装序列化的细节,如果定义在Serializable接口中,就必须定义为public类型,还有就是这样不必强迫用户定义的可序列化类实现这两个方法


// File类:提供了管理文件或目录的方法,File实例表示真实文件系统中的一个文件或者目录,File有以下构造
// File(String pathname),File(String parent, String child),File(File parent, String child)
// 提供很多管理文件的方法:canRead(),canWrite(),delete()包含子目录或文件,则不允许删除File对象代表的目录,exists()文件或目录是否存在
// getAbsolutePath()获取该File对象所代表的文件或者目录的绝对路径,getCanonicalPath()获取该File对象所代表的文件或者目录的正确路径,
// getName(),getParent(),getPath(),isAbsolute()测试该File对象所代表的文件或者目录是否用绝对路径来表示,isDirectory()测试该File对象是否代表一个目录
// isFile()是否代表一个文件,lastModified()最近一次被修改的时间,length()文件的长度,String[] list()返回目录下所有文件和目录的名字列表
// mkdir()创建目录,mkdirs()如果父目录不存在,则创建所有父目录,renameTo(File file)更改文件名,createNewFile()创建文件


// 文件过滤器
// public interface FilenameFilter{public boolean accept(File dir,String name)}
// File类的list(FilenameFilter filter)和listFiles(FilenameFilter filter)方法会调用FilenameFilter对象的accept()方法,这种调用过程称为回调

// File类的list()和listFiles()方法实现了基本的功能,此外,在运行时还采用FilenameFilter对象提供的策略,这种设计模式称为策略设计模式,用户可以在FilenameFilter实现类中指定具体的策略

public class Test22{

	public static void main(String[] args) throws Exception {
		
		// 文件过滤器
		File dir = new File("D:\\");
		
		FilenameFilter filter = new FilenameFilter(){

			@Override
			public boolean accept(File dir, String name) {
				System.out.println("根路径:" + dir.getPath() + "子路径:" + name);
				File currFile = new File(dir,name);
				if(currFile.isFile()&&name.indexOf(".txt")!=-1){
					return true;
				}else{
					return false;
				}
			}
		};
		
		// 仅仅返回D:\目录下扩展名为".txt"的文件清单
		String[] lists = new File("D:\\").list(filter);
		for (int i = 0; i < lists.length; i++) {
			System.out.println(lists[i]);
		}
		
		// 序列化与反序列化
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:\\objectFile.obj"));
		Customer1 obj3 = new Customer1("Tom",30,"123456");
		out.writeObject(obj3);
		out.close();
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\\objectFile.obj"));
		Customer1 obj33 = (Customer1)in.readObject();
		System.out.println("obj33:"+obj33);
		System.out.println("obj33==obj3:" + (obj33==obj3));
		System.out.println("obj33.equals(obj3):" + (obj33.equals(obj3)));
		in.close();
	}
}

class Customer1 implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 8100235502061871961L;
	private String name;
	private int age;
	private transient String password;
	public Customer1(String name, int age, String password) {
		this.name = name;
		this.age = age;
		this.password = password;
	}
	
	public boolean equals(Object o){
		if(this==o)return true;
		if(!(o instanceof Customer1))return false;
		final Customer1 other = (Customer1)o;
		if(this.name.equals(other.name)&&this.age == other.age){
			return true;
		}else{
			return false;
		}
	}
	public String toString(){return "name="+name+",age="+age;}
	
	private byte[] change(byte[] buff){
		for (int i = 0; i < buff.length; i++) {
			int b = 0;
			for (int j = 0; j < 8; j++) {
				int bit = (buff[i]>>j & 1)==0?1:0;
				b+=(1<<j)*bit;
			}
			buff[i]=(byte)b;
		}
		return buff;
	}
	
	private void writeObject(ObjectOutputStream stream) throws Exception{
		stream.defaultWriteObject();
		stream.writeObject(change(password.getBytes()));
	}
	
	private void readObject(ObjectInputStream stream) throws Exception{
		stream.defaultReadObject();
		byte[] buff = (byte[])stream.readObject();
		password = new String(change(buff));
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值