前面我们学习了IO流的字节输入输出流,可以帮助我们很好地读取和输入一些数据,但是当我们想让它更快的读取和输出出来,有没有更加高效的流呢?
这时就需要我们的字节缓冲输入流(BufferedInputStream)和字节缓冲输出流(BufferedOutputStream)
BufferedOutputStream:
字节缓冲输出流:
构造方式:
(第一种开发中使用多) public BufferedOutputStream(OutputStream out):采用的默认的缓冲区大小(足够大了) ,来构造一个字节缓冲输出流对象
public BufferedOutputStream(OutputStream out,int size):指定size缓冲区大小构造缓冲输出流对象
写数据的方式:
一次写一个字节
write(int by)
一次写一个字节数组的一部分
write(byte[] b, int off, int len)
package com.westos.BufferedStream; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class BufferedOutputStreamDome { /** * @param args * @throws IOException * 使用字节缓冲输出流去给文本中写入数据,这样比普通字节输出流更加高效 */ public static void main(String[] args) throws IOException { //创建字节缓冲输出流对象 BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("file.txt")); //写数据 bos.write("迪丽热巴最美丽".getBytes()); //关闭资源 bos.close(); } }
BufferedInputStream:
构造方式:
public BufferedInputStream(InputStream in):默认缓冲区大小构造缓冲输入流对象
public BufferedInputStream(InputStream in,int size):指定缓冲区大小构造缓冲输入流对象
写数据的方式:
public int read()
public int read(byte[] b,int off,int len)
在使输入流的时候,
两种方式读取(一次读取一个字节/一次读取一个字节数在),只能用一种方式,否则,会出现错误!
package com.westos.BufferedStream; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class BufferedInputStreamDome { public static void main(String[] args) throws IOException { //创建字节缓冲输入流对象 BufferedInputStream bis=new BufferedInputStream(new FileInputStream("file.txt")); /* //一次读取一个字节 int len=0; while((len=bis.read())!=-1) { System.out.print((char)len); } bis.close(); */ //一次读取一个数组 byte[] bys=new byte[1024]; int len=0; while((len=bis.read(bys))!=-1) { String str = new String(bys,0,len); System.out.println(str); } bis.close(); } }
我们前面了解到IO流按流的类型分为字节流和字符流,我们已经了解了字节流,接下来让我们再看看字符流:
字符流的引入:
package com.westos.BufferedStream; import java.io.IOException; import java.util.Arrays; /** * @author 杰哥 *编码和解码的时候,其中的格式一定要相同,不能前后不一 *否则就会出现乱码的现象 *系统默认的编码格式是gbk *gbk中:一个中文对应两个字节 *utf-8中:一个字节对应三个字节 */ public class StringDome { public static void main(String[] args) throws IOException { //编码 //定义一个字符串 String str="迪丽热巴最美"; //这里的"gbk"可以不写,因为系统默认是编码格式是"gbk",但是当你用utf-8格式时,必须的写好,下面解码中的格式也必须统一utf-8 byte[] bys = str.getBytes("gbk"); //将字节数组转变成字符串 System.out.println(Arrays.toString(bys)); System.out.println("-------------------------------------"); //解码 //这里String里面的"gbk"也可以不写,同样是默认的 String st=new String(bys,"gbk"); System.out.println(st); } } 运行结果: [-75, -49, -64, -10, -56, -56, -80, -51, -41, -18, -61, -64] ------------------------------------- 迪丽热巴最美
当我们使用字节流去读取有中文的数据时,会出现乱码的现象,这就是前后的格式不同
所以,就需要我们的字符流了
字符流
字符流分为字符输出流(writer)和字符输入流(reader),因为字符流都是抽象类,所以不能创建对象,因此需要它的子类来创建对象
例如:
package com.westos.WritreReader; import java.io.FileInputStream; import java.io.InputStreamReader; /** * @author 杰哥 *将文本中的内容输出到控制台上 */ public class WriterReaderDome { public static void main(String[] args) throws Exception { //创建字符输入流 InputStreamReader isr=new InputStreamReader(new FileInputStream("file.txt"),"gbk"); //一次获取一个字节 // int by=0; // while((by=isr.read())!=-1) { // System.out.print((char)by); // } //一次读取一个数组 char[] bys=new char[1024]; int len=0; while((len=isr.read(bys))!=-1) { System.out.println(new String(bys,0,len));; } //关闭资源 isr.close(); } }
从上述代码中我们可以看出创建字符输入流的代码过于繁琐,因此我们可以寻找一个便捷类(FileReader)来代替它
例如:
字符输入流读数据的方法:
int read(char[] chs):读取一个字符数组
int read():读取单个字符
package com.westos.WritreReader; import java.io.FileReader; import java.io.IOException; public class FileReaderDome { public static void main(String[] args) throws IOException { //创建字符输入流 FileReader fr=new FileReader("file.txt"); /* //一次读取一个字节 int len=0; while((len=fr.read())!=-1) { System.out.print((char)len); } */ //一次读取一个数组 char[] ch=new char[1024]; int len=0; while((len=fr.read(ch))!=-1) { System.out.println(new String(ch,0,len)); } //关闭资源 fr.close(); } }
这样可以看出便捷类的代码相对简单些,在字符输入流有(FileReader便捷类),那么字符输出流也有(FileWeiter便捷类)
下面我们看看怎么将文件中的数据复制到另一个文件中去?
例如:
package com.westos.WritreReader; import java.io.FileReader; import java.io.FileWriter; /** * @author 杰哥 *需求:进行文本的copy * 使用便捷类进行以下操作 * 将文本中的数据copy到另一个文本中 */ public class TextDome { public static void main(String[] args) throws Exception { //创建源文件对象和目的地文件对象 FileReader fr=new FileReader("file.txt"); FileWriter fw=new FileWriter("f.txt"); //一次读取一个数组 char[] ch=new char[1024]; int len=0; //一边读取一边写 while((len=fr.read(ch))!=-1) { fw.write(ch,0,len); } //关闭资源 fr.close(); fw.close(); } }
字符输出流写数据的功能:
public void write(int c):写单个字符
public void write(char[] cbuf):写字符数组
public abstract void write(char[] cbuf, int off, int len):写字符数组的一部分
public void write(String str):写字符串
public void write(String str,int off, int len):写字符串的某一部分
flush和close方法的区别?
close:关闭该流,关闭该流对象以及它关联 的资源文件,关闭之后,不能再对流对象进行操作了,否则会有异常
flush:刷新该流,为了防止一些文件(图片文件/音频文件),缺失,或者没有加载到流对象中,刷新了该流,还是可以流对象进行操作
例如:
package com.westos.WritreReader; import java.io.FileWriter; public class FileWriterDome { public static void main(String[] args) throws Exception { //创建字符输出流 FileWriter fw=new FileWriter("a.txt"); //public void write(int c):写单个字符 fw.write('a'); //public void write(char[] cbuf):写字符数组 char[] ch= {'a','b','c','d'}; fw.write(ch); //public abstract void write(char[] cbuf, int off, int len):写字符数组的一部分 fw.write(ch,0,3); //public void write(String str):写字符串,这个用的最多 String str="RNG夺冠了"; fw.write(str); //public void write(String str,int off, int len):写字符串的某一部分 fw.write(str,0,3); //对字符流进行刷新 fw.flush(); fw.close(); } }
字节流中有更高效的字节缓冲流,那么在字符流中依然有高效的字符缓冲流
接下来让我们先看看字符缓冲输出流(BufferedWriter)
BufferedWriter:字符缓冲输出流
构造方法:
BufferedWriter(Writer out) :默认缓冲区大小构造字符缓冲输出流对象
BufferedWriter(Writer out,int size):指定缓冲区大小
例如:
package com.westos.BufferedDome; import java.io.BufferedWriter; import java.io.FileWriter; public class BufferedWriterDome { public static void main(String[] args) throws Exception { //创建字符缓冲输出流 BufferedWriter bw=new BufferedWriter(new FileWriter("b.txt")); //写入数据 bw.write(new String("迪丽热巴")); bw.write(new String("最美")); //刷新流并关闭,记住刷新的方法一定要写在关闭方法之前 bw.flush(); bw.close(); } }
BufferedReader:字符缓冲输入流
构造方法:
public BufferedReader(Reader in)创建一个使用默认大小输入缓冲区的缓冲字符输入流。
public BufferedReader(Reader in, int sz)创建一个使用指定大小输入缓冲区的缓冲字符输入流。
例如:
package com.westos.BufferedDome; import java.io.BufferedReader; import java.io.FileReader; public class BufferedReaderDome { public static void main(String[] args) throws Exception { //创建字符缓冲输入流 BufferedReader br=new BufferedReader(new FileReader("file.txt")); //直接一个数组的读取 char[] ch=new char[1024]; int len=0; while((len=br.read(ch))!=-1) { System.out.println(new String(ch,0,len)); } //关闭资源 br.close(); } }