序列化与反序列化
序列化:将Java对象转为字节序列的过程
简单描述:将不可传输的类型转为可传输的
反序列化:将字节序列转为Java对象的过程
ObjectOutputStream
将Java对象通过流完成持久化(序列化流)
构造方法:需要一个字节输出流(OutputStream)作为参数
方法
writeObject(obj) :将一个对象通过流写入文件中
这个对象要想序列化必须实现Serializable (序列化接口)
Serializable接口没有方法,仅仅只是一个标记接口,用于标识实现它的类可以序列化
FileOutputStream fileStream = new FileOutputStream("D:\\jar包\\IO\\File\\d.txt");
ObjectOutputStream obj = new ObjectOutputStream(fileStream);
Person person = new Person("张三");
obj.writeObject(person);
obj.close();
public class Person implements Serializable {
String name;
...
}
ObjectInputStream
用流中读取对象的流(反序列化流)
构造方法:需要一个字节输入流(InputStream)作为参数
方法
readObject(obj) :通过流读取对象文件
FileInputStream file = new FileInputStream("D:\\jar包\\IO\\File\\d.txt");
ObjectInputStream obj = new ObjectInputStream(file);
Object b = obj.readObject();
System.out.println(b);
静态属性不能序列化,但是读取时有默认值
transient
transient关键字用于阻止成员属性的序列化,用法和显示结果和static一样
public class Person implements Serializable {
private transient String name;
...
}
序列号冲突
当序列化写入对象后,修改对象的源代码
反序列化读取对象,就会发生序列号冲突
当编译器运行对象时会自动生成一个序列号,序列化时和对象一起写入文件
当对象代码修改后,编译器运行对象时会再次生成一个新的序列号
这是用反序列化去读取文件中的对象及序列号,与修改后的新序列号对比
不一致,报序列号冲突异常
解决:自定义一个不变的序列号
public class Person implements Serializable {
String name;
static final long serialVersionUID = 1L;
...
}
打印流
为其它流提供功能,不会发生IO异常
PrintStream:字节流
PrintWriter:字符流
以上两个流的方法一致
只是构造器的参数不同
PrintStream可以接受File对象,String文件名,字节流输出流OutputStream
PrintWriter可以接受File对象,String文件名,字节流输出流OutputStream
和字符输出流Writer
方法:
print(...)将数据打印进文件
println(...)将数据打印进文件后换行
PrintWriter writer = new PrintWriter("D:\\jar包\\IO\\File\\d.txt");
writer.print(100);
writer.write(97);
writer.close();
System.out.println();
流的自动刷新
自动刷新的条件
1.必须传入一个OutputStream或者Writer作为构造器的参数
2.调用的方法必须是println / printf / format三个方法之一
FileWriter f = new FileWriter("D:\\jar包\\IO\\File\\d.txt");
PrintWriter writer = new PrintWriter(f, true);
writer.println(99);
writer.println(100);
writer.println(101);
writer.close();
IO工具类
commons-io.jar Apache提供的工具jar包
可以去https://mvnrepository.com/ 地址下载各种的jar包
Eclipse导入jar包
新建lib文件夹(存放所有的外部引用jar包)
jar包右键build path就导入了jar包
没有build path就切换视图
window——show view——package Explorer
FilenameUtils
用来处理文件名的(可以包含文件路径)类
常用方法:
statcic String getExtension(filename):获取文件的后缀名
statcic String getName():返回文件名或者最后一个文件夹名或空字符串
statcic boolean isExtension(filename,s):判断filename是否是s后缀名
String string = FilenameUtils.getExtension("c:\\a.txt");
System.out.println(string);
String string2 = FilenameUtils.getName("c:\\a.txt");
System.out.println(string2);
boolean extension = FilenameUtils.isExtension("c:\\a.txt", "exe");
System.out.println(extension);
FileUtils
提供文件操作的类
常用方法:
readFileToString(File file):读取文件内容,并返回一个String
writeStringToFile(File f,String con):将con内容写入文件对象中
copyDirectoryToDirectory(File f,File e):文件夹复制
copyFile(File f,File e):文件复制
String readFileToString = FileUtils.readFileToString(new File("D:\\jar包\\IO\\File\\d.txt"), "utf-8");
System.out.println(readFileToString);
FileUtils.writeStringToFile(new File("D:\\jar包\\IO\\File\\d.txt"), "test");
FileUtils.copyFile(new File("c:\\a.jpg"), new File("d:\\d.jpg"));