一:字节流:
1.输入字节流:InputStream(子类为FileInputStream);
输出字节流:OutputStream(子类为FileOutputStream);
但是由于这些字节流每一次读取或写入都需要与磁盘进行接触,效率太低,因此我们出现了一个BufferedInputStream和BufferedOutputStream来缓冲,每次缓冲满了就与磁盘进行接触,减少了接触次数来提高效率。
举例:比较不加缓冲的功能的读取与加缓冲的功能的读取的效率。
未优化的代码:
public class Demo1 {
public static void main(String[] args)throws IOException {
long start = System.currentTimeMillis();
FileInputStream stream = new FileInputStream("F:\\java知识\\day09\\avi\\02_String练习_字符串反转.exe");
while (true){
int i = stream.read();
if(i==-1){
break;
}
}
stream.close();
long end = System.currentTimeMillis();
long time=end-start;
System.out.println("共耗时"+time);
}
}
优化后代码:
public class Demo2 {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
BufferedInputStream reader = new BufferedInputStream(new FileInputStream("F:\\java知识\\day09\\avi\\02_String练习_字符串反转.exe"));
while(true){
int read = reader.read();
if(read==-1){
break;
}
}
long end = System.currentTimeMillis();
long time =end-start;
System.out.println("优化后的时间为:"+time);
}
}
结果:
2:ByteInputStream和ByteOutputStream的介绍:
它们是将一个数组转化为输入流或者是将字节写入一个数组当中去
举例:
public class Demo3 {
public static void main(String[] args) {
//读取
ByteArrayInputStream bytes = new ByteArrayInputStream(new byte[]{1, 2, 3});
while(true){
int i = bytes.read();
if(i==-1){
break;
}
System.out.println(i);
}
System.out.println("-------------------");
//写入
ByteArrayOutputStream stream = new ByteArrayOutputStream();
stream.write(3);
stream.write(4);
stream.write(98);
byte[] bytes1 = stream.toByteArray();
System.out.println(Arrays.toString(bytes1));
}
}
结果:
二:字符流
1:概述:分为Reader和Writer两个类
2:Reader的介绍
Reader:InputStreamReader:可以将一个字节流转换为字符流
BufferedReader:增强功能可以将按行来读取(装饰者模式);
FileReader:(在读取的时候字符的编码格式为系统默认的格式不可以随意更改)
3:Writer的介绍:
Writer:InputStreamWriter:可以将字节流转化为字符流
BufferedWriter :可以按行来写入
PrintWriter:也是可以按行来写入
Writer:将字符来写入;
print:将字符转换为字符串来写入
FileWriter也是固定了格式
三:序列化
1:序列化的概述:将一个文件转换为一个字节序列并且存储起来的过程(可实现永久保存);
2:如何实现序列化:
(1)首先要让类实现一个Serializable的接口;(注意:如果没有实现Serializable的接口的话就会报出NotSerializableException的异常)
(2)然后利用ObjectOutputStream来写入需要序列化的对象,要求对象的属性都是可以序列化的,如果某个属性不想被实例化的话就要加一个关键字transient
举例:
public class Demo4 {
public static void main(String[] args) throws IOException {
//一个对象的序列化
Person p=new Person();
p.setName("张三");
p.setAge(10);
ObjectOutputStream os=new ObjectOutputStream(new FileOutputS![这里写图片描述](https://img-blog.csdn.net/20180811232808235?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDg0MzYyNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)tream("D:\\p.txt"));
os.writeObject(p);
os.writeObject("3");
os.close();
}
}
结果:
四:反序列化
1:反序列化的概述:将字节内容转换为一个对象ObjectInputStream读取字节的内容,将其转换为java对象,不仅可以读取一个对象还可以读取或写入基本类型,但是注意写入与读取的顺序要保持一致,否则就会出现EOFException
建议在文件的最后一个对象中加入null值,这样就可以判断是否被读取完毕
举例:
public class Demo5 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("D:\\p.txt"));
Person o = (Person) inputStream.readObject();
System.out.println(o.toString());
System.out.println(o.getName());
}
}
结果:
五:创建对象的几种方式
(1):经常使用的new来创建一个对象
(2):反序列化来创建一个新的对象
(3):克隆
下面先对克隆来进行一个介绍
首先克隆一个对象就要对这个对象实现一个Cloneable的接口,再去调用clone方法。
为什么要克隆?
克隆的对象可能包含一些已经修改过的属性,而new出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠clone方法了。
注意:使用Cloneable接口和clone克隆的对象,仅仅是浅拷贝,如果属性为引用类型,复制的仅是地址。没有为这个属性创建新的对象
举例:
public class Demo {
public static void main(String[] args) throws CloneNotSupportedException {
Person p=new Person();
p.setName("张三");
p.setAge(20);
Person o =(Person) p.clone();
o.setAge(29);
o.setName("张思");
System.out.println(p.getName());
System.out.println(p.getAge());
System.out.println(o==p);
}
}
结果:
深拷贝 利用序列化和反序列化生成新的对象,也会为属性创建新的对象
举例:
public class Teacher2 implements Serializable {
private int id;
private String name;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher2 clone() {
try {
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(this); // 写入当前对象
byte[] bytes = bos.toByteArray(); // 字节结果
// 反序列化
ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(bytes));
Teacher2 t = (Teacher2)is.readObject();
return t;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
Teacher2 t = new Teacher2();
t.setId(1);
t.setName("张三");
t.setBirthday(new Date());
Teacher2 t2 = t.clone();
System.out.println(t == t2);
System.out.println(t2.getBirthday());
System.out.println(t.getBirthday());
System.out.println(t.getBirthday() == t2.getBirthday());
}
}
结果: