流主要分为输入流和输出流
字节流和字符流按照流输入输出类型分为字节流和字符流,InputSteam和OutputSteam即字节流输入流和输出流的抽象父类(即带Steam后缀的是字节流),Writer和Reader是字符流输入输出流的抽象父类(即带Reader/Writee后缀的是字符流)。
文件流文件流就是对文件进行的输入输出操作的流既可用字节流作为文件输入输出流即(FileInputSteam/FileOutputSteam)也可以用字符流(FileWriter/FileReader)。
缓冲流(包装流)即在字节流和字符流输入输出流前加上Buffered前缀,缓冲流的作用是会在缓冲区建立一个内部缓冲区数组(8KB)。此外还提供了readLine()方法,以文本行为单位读取数据。
转换流InputSteamReader、OutputSteamWriter即把字节装换为字符。
对象流ObjectInputStream/ObjectOutputStream是以对象作为流的核心输入输出,作用是将对象序列化和反序列化。
序列化:将内存中的对象写入到硬盘中使用的是ObjectOutputStream 反序列化:将硬盘的对象数据读入内存中使用的是ObjectInputStream其中序列化的对象一定要实现Serializable接口,Serializable接口是个标识接口这个接口中是空的,其作用就是给JVM识别的;每个实现了Serializable接口的类中都会有一个serialVersionUID属性它是一个常数,并且它是全球唯一的,这也就是用于反序列化的,当你没有自定义的serialVersionUID时JVM通过识别实现Serializable接口默认给serialVersionUID一个值。一旦这个值被确定下来它就是不可改的!!
我序列化好了一个people对象,过了一段时间,项目的需求发生一些改变,需要给people类增加一个属性。于是乎,我改了代码。
但是,其他同事想要反序列化原来的user对象。这时候,会出现序列化版本号不一致。非法类异常的错误。这是因为我们没有自定义序列化版本号而是使用的JVM默认给我们的,那么我们这个people类没增加一个属性他的序列号的版本号就会改变自然再去比对之前的版本号就对不上了!
解决方法:我们可以自定义一个全球唯一的序列化版本号,这样即使是你加了多个属性也可以把之前的对象反序列化出来只不过多加的属性会给它赋上默认值。
流的使用package com.IOTest;
import java.io.*;
public class Test {
public static void main(String[] args) {
File file = new File("D:\java\src\File\xxx.txt");//确定源
if(!file.exists()) {
try {
file.createNewFile();
} catch (IOException ex) {
ex.printStackTrace();
}
}
File file1 = new File("D:\java\src\File\xxxx.txt");//确定源
FileOutputStream fo = null;
FileInputStream fi = null;
try {
fo = new FileOutputStream(file);//打开流
fi = new FileInputStream(file1);//打开流
byte[] bytes = new byte[10];//操作流
while (fi.read(bytes)!=-1) {
fo.write(bytes);
fo.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fo != null) {
try {
fo.close();//关闭流
} catch (IOException e) {
e.printStackTrace();
}
if (fi != null) {
try {
fi.close();//关闭流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}



