一、流的定义
定义:内存与存储设备之间传输数据的通道
程序是在内存中运行的,文件在硬盘上,如果想要读取硬盘上的文件,需要在内存和硬盘之间建立一个通道
二、流的分类
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数组中所有字节,写入输出流
案例:文件字节输入输出流的使用
packagecom.monv.chapter15;importjava.io.FileInputStream;/*** 演示FileInputStream的使用
* 文件字节输入流
*@authorMonv
**/
public classDemo1 {public static void main(String[] args) throwsException {//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("读取完毕");
}
}--------------------------------------------------------------------
packagecom.monv.chapter15;importjava.io.FileOutputStream;/*** 演示文件字节输出流的使用
* FileOutputStream
*@authorMonv
**/
public classDemo2 {public static void main(String[] args) throwsException{//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("执行完毕");
}
}---------------------------------------------------------
packagecom.monv.chapter15;importjava.io.FileInputStream;importjava.io.FileOutputStream;/*** 使用文件字节流来实现文件的复制
*@authorMonv
**/
public classDemo3 {public static void main(String[] args) throwsException {//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:使用缓冲流来读写数据
packagecom.monv.chapter15;importjava.io.BufferedInputStream;importjava.io.FileInputStream;/*** 使用字节缓冲流读取
* BufferedInputStream
*@authorMonv
**/
public classDemo4 {public static void main(String[] args) throwsException {//1.创建BufferedInputStream
FileInputStream fis = new FileInputStream("D:\\aaa.txt");
BufferedInputStream bis= newBufferedInputStream(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("执行完毕");
}
}--------------------------------------------------
packagecom.monv.chapter15;importjava.io.BufferedOutputStream;importjava.io.FileOutputStream;/*** 使用字节缓冲流写入数据
*@authorMonv
**/
public classDemo5 {public static void main(String[] args) throwsException{//1.创建字节流 及 字节缓冲流
FileOutputStream fos = new FileOutputStream("D:\\001.txt");
BufferedOutputStream bos= newBufferedOutputStream(fos);//2.写入文件
for(int i =0;i<10;i++) {
bos.write("HelloWorld ".getBytes());//写入8k缓冲区
bos.flush();//刷新到硬盘
}//关闭(内部会调用flush)
bos.close();
}
}
案例2:使用对象流来读写数据
--------------------学生类--------------------------
packagecom.monv.chapter15;/*** 要想这个对象可以序列化 必须 要实现 Serializable接口*/
importjava.io.Serializable;public class Student implementsSerializable{/*** serialVersionUID:序列化版本号ID,保证序列化的类和反序列化的类是同一个类*/
private static final long serialVersionUID = 100L;privateString name;private transient intage;private static String country ="中国";publicStudent() {//TODO Auto-generated constructor stub
}public Student(String name, intage) {super();this.name =name;this.age =age;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}
@OverridepublicString toString() {return "Student [name=" + name + ", age=" + age + "]";
}
}------------------------序列化操作-------------------------------
packagecom.monv.chapter15;importjava.io.FileOutputStream;importjava.io.ObjectOutputStream;importjava.util.ArrayList;/*** 使用ObjectOutputStream实现对象的序列化
* 注意事项:
* (1)序列化类必须实现Serializable接口
* (2)序列化类中对象属性要求实现Serializable接口
* (3)序列化版本号ID serialVersionUID ,保证序列化的类和反序列化的类是同一个类
* (4)使用transient(瞬间的)修饰属性,这个属性就不能序列化
* (5)静态属性也是不能序列化的(不能保存到硬盘上)
* (6)序列化多个对象的时候 可以借助集合来实现
*@authorMonv
**/
public classDemo6 {public static void main(String[] args) throwsException{//1.创建对象流 需要借助文件流
FileOutputStream fos = new FileOutputStream("D:\\Stu.bin");
ObjectOutputStream oos= newObjectOutputStream(fos);//2.序列化 就是写入操作
Student s1 = new Student("张三",20);
Student s2= new Student("李四",21);
ArrayList list = new ArrayList<>();
list.add(s1);
list.add(s2);
oos.writeObject(list);//oos.writeObject(s1);//oos.writeObject(s2);//3关闭
oos.close();
System.out.println("序列化完毕");
}
}-----------------------反序列化操作------------------------------
packagecom.monv.chapter15;importjava.io.FileInputStream;importjava.io.ObjectInputStream;importjava.util.ArrayList;/*** 使用ObjectInputStream实现反序列化(读取重构生成对象)
*@authorMonv
**/
public classDemo7 {public static void main(String[] args) throwsException{//1.创建对象
FileInputStream fis = new FileInputStream("D:\\\\Stu.bin");
ObjectInputStream ois= newObjectInputStream(fis);//2.读取对象 只写入了一个对象 不能读多个 读完一次再读就会报错//Student s1 = (Student)ois.readObject();//Student s2 = (Student)ois.readObject();//只写入了一个对象的情况下 不能读多次 第二次读会报错(java.io.EOFException 读取到文件尾部的标志)
ArrayList list = (ArrayList)ois.readObject();//3.关闭
ois.close();
System.out.println("反序列化执行完毕");//System.out.println(s1.toString());//System.out.println(s2.toString());
System.out.println(list.toString());
}
}-------------------------------------------------------------