前言:按照数据的传输方向分为输入流和输出流;流也可以从数据编码格式上划分为字节流和字符流;根据封装类型不同流又分为节点流和处理流。
📌 字节流
📌 字节流中常用类及基本方法:
- 字节输入流 InputStream
- 字节输出流 OutputStream
○ InputStream的基本方法
- 读取一个字节并以整数的形式返回(0~255),如果返回-1已到输入流的末尾。
- int read() throws IOException
- 读取一系列字节并存储到一个数组buffer, 返回实际读取的字节数,如果读取前已到输入流的末尾返回-1
- int read(byte[] buffer) throws IOException
- 关闭流释放内存资源
- void close() throws IOException
○ OutputStream的基本方法
- 向输出流中写入一个字节数据,该字节数据为参数b的低8位
- void write(int b) throws IOException
- 将一个字节类型的数组中的从指定位置(off)开始的 len个字节写入到输出流
- void write(byte[] b, int off, int len) throws IOException
- 关闭流释放内存资源
- void close() throws IOException
📌 代码演示:
public static void main(String[] args) throws IOException {
FileInputStream inputStream =new FileInputStream("D:/demo1.txt");
FileOutputStream outputStream=new FileOutputStream("E:/IO.txt");
byte[] bytes =new byte[10];
//read(bytes) 一次读byte数组长度个字节,文件内容读取完后返回-1
//size:每次实际往数组中装入的元素的个数
int size =0;
while((size=inputStream.read(bytes))!=-1){
//一次向外写出一个byte数组长度个字节内容,从指定位置开始写,写size个
outputStream.write(bytes,0,size);
}
//关闭通道
inputStream.close();
outputStream.close();
}
📌 字符流
📌 字符流中的常用类及基本方法:
- 输入字符流 Reader
- 输出字符流 Writer
○ Reader 的基本方法:
- 读取一个字符并以整数的形式返回, 如果返回-1已到输入流的末尾。
- int read() throws IOException
- 读取一系列字符并存储到一个数组buffer, 返回实际读取的字符数, 如果读取前已到输入流的末尾返回-1。
- int read( char[] cbuf) throws IOException
- 关闭 void close() throws IOException
○ Writer 的基本方法:
- 向输出流中写入一个字符数据,该字节数据为参数b的16位
- void write(int c) throws IOException
- 一个字符类型的数组中的数据写入输出流
- void write( char[] cbuf) throws IOException
- 将一个字符类型的数组中的从指定位置(off set)开始的 length个字符写入到输出流
- void write( char[] cbuf, int off set, int length) throws IOException
- 关闭 void close() throws IOException
字符流只能读取文本文件
📌 代码测试:
① 我们先创建一个char1.txt文本, 并写入内容进行读写测试
② 通过代码将char1.txt文本的内容读写到char2.txt文本
public static void main(String[] args) throws IOException {
FileReader reader =new FileReader("E:/char1.txt");
FileWriter writer =new FileWriter("E:/char2.txt");
int b = 0;
while((b=reader.read())!=-1) {
System.out.println(b);//打印字符编码
writer.write(b);
}
reader.close();
writer.close();
}
字符流读取时以字符为单位,会将读到字节结合编码表转换为一个字符编码
③ 我们可以将每次读取到的字符对应的编码打印出来
④ 成功读写内容到char2.txt文本
📌 上述写法的弊端:
每次运行程序会将之前所读写的内容覆盖带掉,不能做到在原内容的基础上续写
• 解决方法:在字符输出流的对象路径后加上true, 表示可续写.
• 此时当我们多次运行程序时, 发现之前的所读写的内容依然存在
📌 那么我们怎样进行换行操作?
public static void main(String[] args) throws IOException {
FileReader reader =new FileReader("E:/char1.txt");
//保留原来的内容,在原内容基础上向后追加(续写)
FileWriter writer =new FileWriter("E:/char2.txt",true);
BufferedReader bufferedReader =new BufferedReader(reader);
BufferedWriter bufferedWriter =new BufferedWriter(writer);
String line = null ;
while((line=bufferedReader.readLine())!=null){//只要每次读取不为空,则读取一行
bufferedWriter.write(line);//写一行
bufferedWriter.newLine();//插入换行符
}
bufferedReader.close();
bufferedWriter.flush();
bufferedWriter.close();//记得在读写完毕后关闭通道
}
注意: 由于读取一行的方法readLine( )在BufferedReader中,换行方法newLine( )在BufferedWriter类中,所有需要用到缓冲字符输入输出流.
○ 此时当我们多次运行程序时, 会将每次读取到的内容进行换行读写, 便于记录数据
📌 体系图总结
📌 总结 :
○ 字节流:读取时以字节为单位,可以读取任意文件
○ 字符流:读取时以字符为单位,只能读取文本文件
● 字节流中常用类:
- 字节输入流 FileInputStream
- 字节输出流 FileOutputStream
● 字符流中常用类:
- 字符输入流 FileReader
- 字符输出流 FileWriter
- InputStream和OutputStream的子类都是字节流 可以读写二进制文件,主要处理音频、图片、歌曲、字节流处理单元为1个字节。
- Reader和Writer的子类都是字符流, 主要处理字符或字符串,字符流处理单元为1个字符。
📌 节点流与处理流
● 按封装类型,流又分为:
- 节点流:直接封装的是文件,数据.
- 处理流:封装的是其他节点流对象;可以提供缓冲功能,提高读写效率.
● 节点流中常用类:
- 字节输入流 FileInputStream
- 字节输出流 FileOutputStream
- 字符输入流 FileReader
- 字符输出流 FileWriter
● 处理流中常用类:
- 缓冲字节输出流 BufferedOutputStream
- 缓冲字节输入流 BufferedInputStream
- 缓冲字符输入流 BufferedReader
- 缓冲字符输出流 BufferedWriter
代码演示:
public static void main(String[] args) throws IOException {
FileInputStream inputStream = new FileInputStream("D:/demo1.txt");
//封装的是一个节点流对象,可以提供缓冲功能,称为处理流/包装流
BufferedInputStream bufferedInputStream =new BufferedInputStream(inputStream,20);
FileOutputStream outputStream =new FileOutputStream("E:/IO.txt");
BufferedOutputStream bufferedOutputStream =new BufferedOutputStream(outputStream,20);
int size =0;
byte[] bytes =new byte[10];
while ((size=bufferedInputStream.read(bytes))!=-1){
bufferedOutputStream.write(bytes,0,size);
}
bufferedInputStream.close();
bufferedOutputStream.close();
}
缓存区流底层代码: