所谓缓存流,也就是高级流,它的原理是底层自带了长度为8192的缓冲区提高性能。而在其中有一些方法:
public BufferedInputstream( InputStream is) 把基本流包装成高级流,提高读取数据的性能。
public BufferedOutputStream(outputStream os) 把基本流包装成高级流,提高写出数据的性能。
接下来写一个拷贝文件的案例:
package com.zhou.mybufferedStream1;
import java.io.*;
public class BufferedStreamDemo01 {
public static void main(String[] args) throws IOException {
// 需求:利用字节缓冲流拷贝文件
// 字节缓冲输入流的构造方法:public BufferedInputstream( InputStream is)
// 字节缓冲输出流的构造方法:public BufferedOutputStream(outputStream os)
//1.创建缓冲流的对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\IdeaFile\\MyIO\\AnLi.txt"));
//两个方法当中都有两个构造,第一个是默认长度为8192的缓冲区。
// 第二个则是除了可以传递一个字节输入流以外,还能设定缓冲区大小
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\IdeaFile\\MyIO\\copy.txt"));
//2.循环读取并写到目的地
int b;
while ((b=bis.read()) != -1){
bos.write(b);
}
//3.释放资源
bos.close();
bis.close();
}
}
运行之后,会将已经存在的AnLi.txt拷贝为copy.txt。
另外,释放资源时,只需要关闭高级流,而普通流不用管。
上面案例一次只能读取一个字节,可以对其进行升级,使得其一次能读写一个字节数组,只需申明一个字节数组,将输入的字节保存到数组中,再写出来即可。
在代码中,我们会将读取到的数据转换为基本流再交给缓冲输入流,最后放入缓冲区,因为缓冲区的长度为8192,所以会一次性输入8192个字节,当然,缓冲输出流也是一样的。但是在此处,两者的缓冲区不是一样的,我们声明的其它相关变量则是直接放在两个缓冲区之间,配合二者读取。
同字节缓冲流一样,有两个构造方法:
public BufferedReader( Reader r) 把基本流变成高级流。
public Bufferedwriter(writer r) 把基本流变成高级流。
与字节缓存流不同的是,字符缓冲流拥有两个独有的方法:
字符缓冲输入流特有方法:
public string readLine() 读取一行数据,如果没有数据可读了,会返回null。
字节缓冲输出流特有方法:
public void newLine() 跨平台的换行
接下来写一个字符缓冲输入流特有方法的案例:
package com.zhou.mybufferedStream1;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedStreamDemo2 {
public static void main(String[] args) throws IOException {
/*字符缓冲输入流:
构造方法:public BufferedReader(Reader r)
特有方法:public StringreadLine() */
//1.创建字符缓冲输入流的对象
BufferedReader br = new BufferedReader(new FileReader("D:\\IdeaFile\\MyIO\\AnLi.txt"));
//2.读取数据
String line = br.readLine();
System.out.println(line);
//3.释放资源
br.close();
}
}
运行结果:
该方法只读取一行,遇到换行则不再读取,同时回车换行不会被读到内存当中,若是没有可读取则返回null。
下面给出循环体,该循环体可把所有数据读出:
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
然后再给出一个字符缓冲输出流特有方法的案例:
package com.zhou.mybufferedStream1;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedStreamDemo3 {
public static void main(String[] args) throws IOException {
/*字符缓冲输出流:
构造方法:public BufferedWriter(Writer r)
特有方法:public void newLine() */
//1.创建字符缓冲输出流的对象
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\IdeaFile\\MyIO\\AnLi3.txt"));
//2.写出数据
bw.write("春梦随云散,飞花逐水流。");
bw.newLine();
bw.write("寄言众儿女,何处觅闲愁。");
bw.newLine();
//3.释放资源
bw.close();
}
}
同基本输出流一样,如果没有文件,则会自己创建文件。
其中newLine()起到跨平台换行作用。
运行结果:
转换流是字节流和字符流之间的桥梁,实现字节流和字符流的相互转换。
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
OutputStreamWriter是从字符流到字节流的桥接:使用指定的字符集将写入其中的字符编码为字节。它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。
Out -- 将输出的字符流 ---- > 字节流 ---> 用于输出到控制台 或者 文件 -- 注意这个是写 ====输出的是来源,形容词,不是你理解的字符输出流转字节输出流
In -- 将输入的字节流 -----> 字符流 ---->用于读取到控制台 或 内存 -- 注意这个是读 ====输入的是来源,形容词,不是你理解的字节输入流转字符输入流
作用一:指定字符集读写(已淘汰)
作用二:字节流想要使用字符流中的方法
接下来准备一个GBK编码的文本文档,利用转换流按照指定字符编码读取。
接下来给出代码:
package com.zhou.myconvertstream;
import sun.nio.cs.ext.GBK;
import java.io.*;
public class ConvertStreamDemo01 {
public static void main(String[] args) throws IOException {
char a = '中';
/*利用转换流按照指定字符编码读取*/
//1.创建对象并指定字符编码
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\IdeaFile\\MyIO\\news.txt"), "GBK");//第一个参数放文件,第二个参数放字符编码
//2.读取数据
int ch;
while((ch = isr.read()) != -1){
System.out.print((char)ch);
}
//3.释放资源
isr.close();
}
}
把读取到的字节数据以GBK的方式解码为字符,再将其以char类型输出即可。
接下来展示它的替代方案(该方案对jdk版本有要求):
package com.zhou.myconvertstream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
public class ConvertStreamDemo02 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("D:\\IdeaFile\\MyIO\\news.txt",Charset.forName("GBK"));
int ch;
while((ch = fr.read()) != -1){
System.out.print((char)ch);
}
}
}
下面利用转换流按照指定字符编码输出:
package com.zhou.myconvertstream;
import java.io.*;
public class ConvertStreamDemo02 {
public static void main(String[] args) throws IOException {
/*利用转换流按照指定字符编码输出*/
//1.创建转换流对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\IdeaFile\\MyIO\\news02.txt"),"GBK");
//2.写出数据
osw.write("花容月貌为谁妍");
//3.释放资源
osw.close();
}
}
因为使用的解码方式是GBK,所以当在解码方式为UTF-8的Idea中打开时,会出现下面的情况:
人生建议,不要修改Idea中的编码格式。
我们在文件夹中打开该文档:
当我们实现了读和写之后,就要将两者结合起来,实现将本地GBK文件转换为UTF-8文件。
package com.zhou.myconvertstream;
import java.io.*;
public class ConvertStreamDemo03 {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\IdeaFile\\MyIO\\news.txt"),"GBK");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\IdeaFile\\MyIO\\newss.txt"),"UTF-8");
int b;
while((b = isr.read()) != -1){
osw.write(b);
}
osw.close();
isr.close();
}
}
此代码的目的是,将原本GBK编码的news.txt转换为UTF-8编码的newss.txt。
运行结果如下:
利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码。
package com.zhou.myconvertstream;
import java.io.*;
public class ConvertStreamDemo04 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\IdeaFile\\MyIO\\AnLi.txt")));
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
}
}