一、流的定义
定义:内存与存储设备之间传输数据的通道
程序是在内存中运行的,文件在硬盘上,如果想要读取硬盘上的文件,需要在内存和硬盘之间建立一个通道
二、流的分类
2.1按方向分:
输入流:将<存储设备>中的内容读入到<内存>中
输出流:将<内存>中的内容写入到<存储设备>中
2.2按单位分:
字节流:以字节为单位,可以读写所有数据
字符流:以字符为单位,只能读写文本数据
2.3按功能分:
节点流:具有实际传输数据的读写功能
过滤流:在节点流的基础之上增强功能
三、字节节点流
字节流(抽象类):
InputStream:字节输入流(从存储设备读到内存)
pubic int read(){};//从输入流中读取数据
public int read(byte[] b){};//从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中
public int read(byte[] b,int off,int len){};//将输入流中最多len个数据字节读入byte数组
OutputStream:字节输出流(从内存保存到存储设备)
public int write(int n){}//将指定的字节写入此输出流
public int write(byte[] b){}//将b.length个字节从指定的byte数组写入此输出流
public int write(byte[] b,int off,int len){}//将写指定byte数组中从off位置开始的len个字节写入此输出流
文件字节流:
FileInputStream:public int read(byte[] b)//从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
FileOutputStream: public void write(byte[] b)//一次写多个字节,将b数组中所有字节,写入输出流
案例:文件字节输入输出流的使用
package com.monv.chapter15; import java.io.FileInputStream; /** * 演示FileInputStream的使用 * 文件字节输入流 * @author Monv * */ public class Demo1 { public static void main(String[] args) throws Exception { //1.创建FileInputStream,并指定文件路径 FileInputStream fis = new FileInputStream("D:\\aaa.Txt"); //2.读取文件 //2.1 单个字节读取 将读取的每个字节赋值给Data并输出 =-1的时候 说明读完了 跳出循环 // int data =0; // while ((data = fis.read()) !=-1) { // System.out.println((char)data); // } //2.2一次读取多个字节 byte[] buf = new byte[1024]; int count = 0; while((count = fis.read(buf))!=-1) { System.out.println(new String(buf,0,count)); } //3.关闭 fis.close(); System.out.println("读取完毕"); } } -------------------------------------------------------------------- package com.monv.chapter15; import java.io.FileOutputStream; /** * 演示文件字节输出流的使用 * FileOutputStream * @author Monv * */ public class Demo2 { public static void main(String[] args) throws Exception{ //1创建文件字节输出流对象 第二个参数 为true 表示 在原有文件上追加内容 FileOutputStream fos = new FileOutputStream("D:\\bbb.txt",true); //2.写入文件 // fos.write(97); // fos.write(‘b‘); // fos.write(‘c‘); String str = "HelloWorld"; fos.write(str.getBytes()); //3.关闭 fos.close(); System.out.println("执行完毕"); } } --------------------------------------------------------- package com.monv.chapter15; import java.io.FileInputStream; import java.io.FileOutputStream; /** * 使用文件字节流来实现文件的复制 * @author Monv * */ public class Demo3 { public static void main(String[] args) throws Exception { //1 创建流 //1.1 创建文件字节输入流 FileInputStream fis = new FileInputStream("D:\\111.jpg"); //1.2 创建文件字节输出流 FileOutputStream fos = new FileOutputStream("D:\\222.jpg"); //2 一边读 一遍写 byte[] buf = new byte[1024]; int count = 0; while((count = fis.read(buf)) !=-1) { fos.write(buf,0,count);//不能保证每次读取1024的大小 所以把count传进来 读多少写多少 } //3.关闭 fis.close(); fos.close(); System.out.println("执行完毕"); } }
四、字节过滤流:
缓冲流:BufferedOutputStream/BufferedInputStream
提高IO效率,减少访问磁盘的次数;数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
对象流:ObjectOutputStream/ObjectInputStream
增强了缓冲区功能
增强了读写8种基本数据类型和字符串功能
增强了读写对象的功能:readObject() 从流中读取一个对象
writeObject(Object obj) 向流中写入一个对象
注:使用流传输对象的过程成为序列化(写入文件)、反序列化(读取文件)
对象序列化注意事项:
1)、序列化类必须实现Serializable接口
2)、序列化类中对象属性要求实现Serializable接口
3)、序列化版本号ID serialVersionUID ,保证序列化的类和反序列化的类是同一个类
4)、使用transient(瞬间的)修饰属性,这个属性就不能序列化
5)、静态属性也是不能序列化的(不能保存到硬盘上)
6)、序列化多个对象的时候 可以借助集合来实现
案例1:使用缓冲流来读写数据
package com.monv.chapter15; import java.io.BufferedInputStream; import java.io.FileInputStream; /** * 使用字节缓冲流读取 * BufferedInputStream * @author Monv * */ public class Demo4 { public static void main(String[] args) throws Exception { //1.创建BufferedInputStream FileInputStream fis = new FileInputStream("D:\\aaa.txt"); BufferedInputStream bis = new BufferedInputStream(fis); //2.读取 // int data = 0; // while ((data = bis.read())!= -1 ) { // System.out.print((char)data); // } int count =0; byte[] buf = new byte[1024]; while ((count = bis.read(buf)) != -1) { System.out.print(new String(buf,0,count)); } //3.关闭 只关闭缓冲流就行了 内部 会把fis关掉 bis.close(); System.out.println("执行完毕"); } } -------------------------------------------------- package com.monv.chapter15; import java.io.BufferedOutputStream; import java.io.FileOutputStream; /** * 使用字节缓冲流写入数据 * @author Monv * */ public class Demo5 { public static void main(String[] args) throws Exception{ //1.创建字节流 及 字节缓冲流 FileOutputStream fos = new FileOutputStream("D:\\001.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); //2.写入文件 for(int i =0;i<10;i++) { bos.write("HelloWorld ".getBytes());//写入8k缓冲区 bos.flush();//刷新到硬盘 } //关闭(内部会调用flush) bos.close(); } }
案例2:使用对象流来读写数据
--------------------学生类-------------------------- package com.monv.chapter15; /** * 要想这个对象可以序列化 必须 要实现 Serializable接口 */ import java.io.Serializable; public class Student implements Serializable{ /** * serialVersionUID:序列化版本号ID,保证序列化的类和反序列化的类是同一个类 */ private static final long serialVersionUID = 100L; private String name; private transient int age; private static String country ="中国"; public Student() { // TODO Auto-generated constructor stub } public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } } ------------------------序列化操作------------------------------- package com.monv.chapter15; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; /** * 使用ObjectOutputStream实现对象的序列化 * 注意事项: * (1)序列化类必须实现Serializable接口 * (2)序列化类中对象属性要求实现Serializable接口 * (3)序列化版本号ID serialVersionUID ,保证序列化的类和反序列化的类是同一个类 * (4)使用transient(瞬间的)修饰属性,这个属性就不能序列化 * (5)静态属性也是不能序列化的(不能保存到硬盘上) * (6)序列化多个对象的时候 可以借助集合来实现 * @author Monv * */ public class Demo6 { public static void main(String[] args) throws Exception{ //1.创建对象流 需要借助文件流 FileOutputStream fos = new FileOutputStream("D:\\Stu.bin"); ObjectOutputStream oos = new ObjectOutputStream(fos); //2.序列化 就是写入操作 Student s1 = new Student("张三",20); Student s2 = new Student("李四",21); ArrayList<Student> list = new ArrayList<>(); list.add(s1); list.add(s2); oos.writeObject(list); // oos.writeObject(s1); // oos.writeObject(s2); //3关闭 oos.close(); System.out.println("序列化完毕"); } } -----------------------反序列化操作------------------------------ package com.monv.chapter15; import java.io.FileInputStream; import java.io.ObjectInputStream; import java.util.ArrayList; /** * 使用ObjectInputStream实现反序列化(读取重构生成对象) * @author Monv * */ public class Demo7 { public static void main(String[] args) throws Exception{ //1.创建对象 FileInputStream fis = new FileInputStream("D:\\\\Stu.bin"); ObjectInputStream ois = new ObjectInputStream(fis); //2.读取对象 只写入了一个对象 不能读多个 读完一次再读就会报错 // Student s1 = (Student)ois.readObject(); // Student s2 = (Student)ois.readObject();//只写入了一个对象的情况下 不能读多次 第二次读会报错(java.io.EOFException 读取到文件尾部的标志) ArrayList<Student> list = (ArrayList<Student>)ois.readObject(); //3.关闭 ois.close(); System.out.println("反序列化执行完毕"); // System.out.println(s1.toString()); // System.out.println(s2.toString()); System.out.println(list.toString()); } } -------------------------------------------------------------
Java--流的定义及分类、字节节点流、字节过滤流(缓冲流、对象流)
原文:https://www.cnblogs.com/mo-nv/p/14299197.html