前面我们学习了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();
}
}