IO流

流的分类:
a) 按方向分【重点】(以JVM为参照物)
① 输入流:将 <存储设备> 中的 [数据] 读入到 <内存> 中
② 输出流:将 <内存> 中的 [数据] 写出到 <存储设备> 中
b) 按单位分
① 字节流:以字节为单位,可以操作所有类型的文件
② 字符流:以字符为单位,只能操作文本类型的文件
c) 按功能分
① 节点流:只具备基本的读写功能
② 过滤流:在节点流的基础上,添加了新的功能

1、字节流

1. 字节流父类(抽象类)

a) InputStream:字节输入流
方法:read()
b) OutputStream : 字节输出流
方法:write()

2. 节点流

1、FileOutputStream(文件输出流)

构造方法1:FileOutputStream(String name)
  参数1:文件的路径名 String
  存在已检查异常:必须要处理,否则编译不通过      
  路径:
  1) 绝对路径:电脑盘符/文件夹/文件名
  2) 相对路径:文件夹/文件名 相对于项目
    默认新内容将原有内容覆盖   
构造方法2:FileOutputStream(String name,boolean append)  
  参数1:String name 代表文件路径
  参数2:boolean  是否在原有内容上追加新的内容
     true:在原有内容上追加
     false:覆盖原有内容
普通方法:public void write(char c)  写单个字节到文件中      
注意:如果文件不存在则自动创建文件
如果文件夹不存在则不会创建文件夹,只会抛出异常      
//throws的方式处理异常
public class TestFileOutputStream {
	public static void main(String[] args) throws IOException {
	//FileOutputStream fos = new FileOutputStream("E:/file/a.txt");
	//FileOutputStream fos = new FileOutputStream("file/a.txt",true);
	FileOutputStream fos = new FileOutputStream("file/a.txt");
	//fos.write('A');
	//fos.write(65);
	fos.write('B');
	fos.close();//释放资源(关流)
	}
}

2、FileInputStream (文件输入流)

构造方法  FileInputStream(String fileName)
	 参数:文件路径
	 注意:文件名必须存在,不存在就报错
public int read():一次只读一个字节的内容,返回值代表读到的内容,如果文件读取到末尾则返回-1
	//一次性读一个字节的内容  
	FileInputStream fis = new FileInputStream("file/a.txt");
	int read = fis.read();
	System.out.println((char)read);  
	fis.close();

//循环读取文件的所有内容
while(true) {
	int read = fis.read();
	if(read==-1)break;
	System.out.println((char)read);
}
fis.close();

3、过滤流
a) BufferedOutputStream|BufferedInputStream
① 缓冲流,提高io读写的效率,减少访问磁盘的次数。
② 数据存储在缓冲区。需要调用flush(),将缓冲区中的内容写出到文件中,也可以直接close()

BufferedOutputStream:过滤流(在基本的读写功能上添加一些额外的功能) 建立在节点流的基础之上
构造方法:BufferedOutputStream(OutputStream os) 参数:节点输出流
方法:  void write(int c):一次写一个字节的内容到带有缓冲功能的输出流
//构建节点流
FileOutputStream fos = new FileOutputStream("file/buffered.txt");
//包装过滤流 将节点流作为参数传递给过滤流
BufferedOutputStream bos = new BufferedOutputStream(fos);
//写内容
bos.write('A');//暂时的将内容放在了缓冲区
//bos.flush();//当调用了flush() 会一次性的将缓冲区的内容写出到文件中
bos.close();//直接调用close() 会先调用flush() 将缓冲区的内容清空 


BufferedInputStream
构造方法:BufferedInputStream(InputStream is)  参数:节点输入流 
读方法:public int read():一次读一个字节的内容
//构建节点流
FileInputStream fis = new FileInputStream("file/buffered.txt");
//包装过滤流
BufferedInputStream bis = new BufferedInputStream(fis); 
//读数据
int read = bis.read();
System.out.println((char)read);
int read2 = bis.read();
System.out.println(read2);
bis.close();
//循环读数据
while(true) {
int read = bis.read();
if(read==-1)break;
System.out.println((char)read);
}
bis.close();

b) ObjectOutputStream|ObjectInputStream
① 增强了缓冲区功能
② 增强了读写8种基本数据类型与字符串的功能
③ 增加了读写对象的功能。

ObjectOutputStream 过滤流  输出流
构造方法:ObjectOutputStream(OutputStream os)  参数:节点流
方法: writeDouble(double d):写一个double类型的数据到文件中
  writeLong(long l):写一个long类型的数据到文件中  
 
//1. 创建节点流
FileOutputStream fos = new FileOutputStream("file/object.txt");
//2. 包装过滤流
ObjectOutputStream oos = new ObjectOutputStream(fos);
//3. 写操作
oos.writeDouble(1.5);
oos.writeLong(10L);
//4. 关流
oos.close();     

ObjectInputStream  过滤流  输入流
构造方法:ObjectInputStream(InputStream is)  参数:节点输入流
方法:public double readDouble():从输入流中读取一个double类型的数据
 public long readLong():从输入流中读取一个long类型的数据   
//1. 创建节点输入流
FileInputStream fis = new FileInputStream("file/object.txt");
//2. 包装过滤输入流
ObjectInputStream ois = new ObjectInputStream(fis);
//3. 读操作
double d = ois.readDouble();
long l = ois.readLong();
System.out.println(d);
System.out.println(l);
//4. 关流
ois.close();

对象序列化:将对象放在流上进行传输(读|写)的过程。对象序列化时必须保证对象是可序列化的,要求对象必须实java.io.Serializable接口。(则对象中的所有的自定义属性(除了八种基本类型和string类型)都需要实现Serializable接口。transient可以修饰属性,修饰的属性不参与序列化)

2、字符流

1、 字符流父类(抽象类)
Reader:字符输入流
Writer:字符输出流
2、节点流
FileWriter|FileReader

FileWriter:字符文件输出流(节点流)
构造方法:FileWriter(String fileName)
  参数:文件路径
方法:write():一次写一个字符的内容
//构建字符流
FileWriter fw = new FileWriter("a.txt");
//写数据
fw.write('中');
//关流
fw.close();
FileReader:字符文件输入流(节点流)
构造方法:FileReader(String fileName) 
参数:文件路径
方法:int read():一次读一个字符的内容,返回值为读到的内容,当文件读取到末尾时返回-1 
//构建字符输入流
FileReader fr = new FileReader("a.txt");
//读数据
int read1 = fr.read();
System.out.println((char)read1);
int read2 = fr.read();
System.out.println(read2);//-1
//关流
fr.close();

3、过滤流
PrintWriter|BufferedReader:缓冲流

过滤流:在节点流的基础上添加一些新的功能
PrintWriter:
构造方法:PrintWriter(Writer out)
    参数:字符节点输出流
方法:println(String s) 输出一个字符串到文件中
BufferedReader:
构造方法:BufferedReader(Reader in)
    参数:字符节点输入流
方法:String readLine(): 一次读一行字符串的内容 返回值为读到的一行字符串 当文件读取到末尾时返回null 
//构建字符节点流(输入流)
FileReader fr = new FileReader("file/a.txt");
//包装过滤流
BufferedReader br = new BufferedReader(fr);
//读数据
String s = br.readLine();
System.out.println(s);
String s1 = br.readLine();
System.out.println(s1);//null
//关流
br.close();
//构建字符节点流(输出流)
FileWriter fw = new FileWriter("file/a.txt");
//包装过滤流
PrintWriter pw = new PrintWriter(fw);
//写数据
pw.println("哒哒哒");
pw.close();
//构建字符节点流(输入流)
FileReader fr = new FileReader("file/a.txt");
//包装过滤流
BufferedReader br = new BufferedReader(fr);
//读数据
while(true) {
	String s = br.readLine();
	if(s==null)break;//当文件读取到末尾时返回null 可以作为循环结束的条件
	System.out.println(s);
}
	//关流
	br.close();

4、桥转换流
InputStreamReader|OutputStreamWriter
作用:将字节流转换成字符流,转换的桥梁,同时还可以设置字符的编码格式。

InputStreamReader
构造方法:InputStreamReader(InputStream is,String charsetName)
  参数1:字节输入流
  参数2:字符串类型的编码格式
OutputStreamWriter
构造方法:OutputStreamWriter(OutputStream out,String charsetName)
  参数1:字节输出流
  参数2:字符串类型的编码格式
PrintWriter pw = null;
try {
	 //1. 创建字节流
	 FileOutputStream out = new FileOutputStream("file/b.txt");
	 //2. 创建桥转换流 并设置编码格式
	 OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
	 //3. 包装过滤流
	 pw = new PrintWriter(osw);
 //4. 写数据
	 pw.println("哒哒哒");
}catch (Exception e) {
	 e.printStackTrace();
}finally {
	//5.关流
	pw.close();
}
BufferedReader br = null;
try {
	//1.创建字节流
	FileInputStream fis = new FileInputStream("file/b.txt");
	//2.创建桥转换流 同时设置编码格式
	InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
	//3.创建过滤流
	br = new BufferedReader(isr);
	//4.读数据
while(true) {
	String s = br.readLine();
	  if(s==null)break;
	  System.out.println(s);
}
}catch (Exception e) {
	e.printStackTrace();
}finally {
try {
	//5. 关流
	if(br!=null)br.close();
}catch (Exception e) {
	e.printStackTrace();
}
}