1——关于流的概念
流即为动态数据的集合,在java中将IO流分化为输入流和输出流,都是按照输入和输出方式读取的
注意:所谓输入和输出都是基于程序而言的,下图更好地描述了这一概念。
2——分类
根据Java中不同的划分方式,IO流可以被划分为不同的阵营
1-按流 和 数据处理单元分类
InputStream ——字节输入流 OutputStream——字节输出流
Reader——字符输入流 Writer——字符输出流
小技巧(区分字节字符可以按照末尾是否为Stream,Writer,read。若为Stream则为字节类型,若为字符类型,则为Writer Read)
2-按功能分类
1——节点流:可以直接从数据源读写数据
例如:FileInputStream FileOutputStream
2——处理流:不能直接和数据源链接,需要对其他流进行处理,提高其他流的运行效率,从而提高程序的性能。
例如:BufferedInputStream(字节输入缓冲流,输出流同理)
OutputStreamReader(将字符类型转化为字节类型) InputStreamWriter(将字节类型转化为字符类型)等等
3—java IO流的四大基石
InputStream、OutputStream、Reader、Writer
以下所有实现类都基于此四大基石建立
另附一些使用的实现类:
-
InputStream的实现类:
-
FileInputStream(文件输入字节流)
-
BufferedInputStream(字节输入缓冲流)
-
DataInputStream (数据输入流)
-
ObjectInputStream (对象流) ——个人认为是比较nb的一个实现类 ,类似于冷战时期的一个笑话,,美国曾说自己可以将牛短时间内制作成各式各样的加工品,用来吹嘘自己的机械化强度,而苏联可以说自己可以将所加工的工艺品重新变成奶牛。显然是天方夜谭,但事实上java中的ObjectInputStream便实现了逆序化
-
-
OutputStream的实现类:
-
FileOutputStream (文件字节输出流)
-
BufferedOutputStream (文件输出缓冲流)
-
DataOutputStream (数据输出流)
-
ObjectOutputStream (对象输出流)
-
-
Reader的实现类
-
FileReader (文件字符输入流)
-
BufferedReader (字符输入缓冲流)
-
InputStreamReader (转换流——可以理解为处理流——即是将字节类型转化为字符类型)
-
-
Writer的实现类
-
FileWriter (文件字符输出流)
-
BufferedWriter (字符输出缓冲流)
-
OutputStreamWriter(转换流——处理流——将字符类型转化为字节类型的一个实现类)
-
PrintWriter (字符打印流——是节点流(但是他有着字符缓冲流的特点,是个很便捷的一个实现类)。
-
二——代码详解(下面以文件字节流读取文件并添加行号的操作)
以下包含操作:如何读取并复制一个现有的文件一个新的空间 如何利用文件字符缓冲流替代传统的read和writer方法,快捷 异常抛出机制的格式 利用 装饰器模拟构建IO体系
import java.io.*;
public class TestLineNumber2 {
public static void main(String[] args) {
//1-创建字符输入缓冲流,字符到字节的缓冲流,文件字节输入流对象
try(BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("d:/蔡徐坤.txt")));
//
BufferedWriter bs=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:/蔡徐坤999.txt")))){
//操作流
String temp="";
int i=1;
while((temp=br.readLine())!=null){
bs.write(i+ " . " +temp);
bs.newLine();
i++;
}
}catch(IOException E){
E.printStackTrace();
}
}
}
下面进行内容重点的详解:
1——java中字节类型的read方法只能从文件中一个字一个字的读取,write中是不支持换行操作的,因此操作有一定的复杂度
2——仔细观察要求:文件字节读取文件则需利用FileInputStream实现类,而我们需要将字节类型通过转换类变换成字节类型调用字符缓冲流的方法。其中readLine()是能够一行一行读取数据,而newLine()是可以在输出的时候进行换行操作。因此不难发现我们需要调用三个类型的流 ,文件字节输入/输出流,字符输入/输出缓冲流,字节流到字符流/字符到字节流的桥接器。从而利用以上实现类进行嵌套
小提醒:在进行读取文件等操作抛出异常时,必须在finally后关闭对象对应的操作。而jdk 1.8之后,try-with-resour方法会自动关闭,无需手动调用。
三—对象流的序列化和反序列化
序列化:将对象转化为二进制从而传递出去 反序列化:将二进制转化为对象
首先:创建一个User对象(私有)重写他的setget方法,tostring方法
public class Users implements Serializable {
private int userid;
private String username;
private String userage;
public Users(int userid, String username, String userage) {
this.userid = userid;
this.username = username;
this.userage = userage;
}
public Users() {
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserage() {
return userage;
}
public void setUserage(String userage) {
this.userage = userage;
}
@Override
public String toString() {
return "Users{" +
"userid=" + userid +
", username='" + username + '\'' +
", userage='" + userage + '\'' +
'}';
}
实现序列化
public class TestObjectOutputStream {
public static void main(String[] args) {
//创建对象输出字节流与文件输出字节流对象
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/data3"))){
//创建Users对象
Users users = new Users(1,"Oldlu","18");
oos.writeObject(users);
//刷新
oos.flush();
}catch(IOException e){
e.printStackTrace();
}
}
}
其中write'object是java对象流的一种独有方法,他的作用就是将User对象实现序列化,化为二进制类型的数字。
实现反序列化
public class TestObjectInputStream {
public static void main(String[] args) {
//创建对象输入字节流与文件字节输入流对象
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/data3"))){
//将对象反序列化到内存中
Users users = (Users) ois.readObject();
System.out.println(users);
}catch(Exception e){
e.printStackTrace();
}
}
}
注意:当要对对象进行反序列化时,被序列化的对象必须要实现Serializable接口。此接口并未定义方法,此空接口仅仅起到标记作用,称作标识接口。
——就写到这里,学生能力有限。希望对各位有用。