一、BufferedReader类概念
API文档描述:
BufferedReader类从字符输入流中读取文本并缓冲字符,以便有效地读取字符,数组和行
可以通过构造函数指定缓冲区大小也可以使用默认大小。对于大多数用途,默认值足够大
由Reader构成的每个读取请求都会导致相应的读取请求由基础字符或字节流构成,建议通过BufferedReader包装Reader的实例类以提高效率如
BufferedReader in = new BufferedReader(new FileReader(“foo.in”));
使用DataInputStreams进行文本输入的程序可以通过用适当的BufferedReader替换每个DataInputStream来进行本地化
1)从字符输入流中读取文本并缓冲字符,以便有效地读取字符,数组和行怎么理解?
说明该类存在缓冲字符数组并且是该类可以高效读取字符的关键
2)构造函数指定缓冲区大小也可以使用默认大小怎么理解?
意味着该类存在的构造方法既可以传递数值指定缓冲区大小也可以由类中的默认大小指定
3)提高效率怎么理解?
假设没有缓冲区,读取流程是读取字节转成字符然后返回给调用者,这样的操作需要多次。如果有缓冲区,那么流程是:读取字节转成字符然后存在缓冲区中,读取完毕后一次性返回给调用者,所谓的高效是否指这个地方?
4)DataInputStreams?
暂时不理解什么意思
二、BufferedReader类构造函数
1)使用默认的缓冲区大小来创建缓冲字符输入流--该缓冲区可以缓存8192个字符适用小文件
private static int defaultCharBufferSize = 8192;
public BufferedReader(Reader in) {
this(in, defaultCharBufferSize);
}
public BufferedReader(Reader in, int sz) {
super(in);
if (sz <= 0)
throw new IllegalArgumentException("Buffer size <= 0");
this.in = in;
cb = new char[sz];
nextChar = nChars = 0;
}
2)创建指定缓冲区大小的缓冲字符输入流---适用大文件
public BufferedReader(Reader in, int sz) {
super(in);
if (sz <= 0)
throw new IllegalArgumentException("Buffer size <= 0");
this.in = in;
cb = new char[sz];
nextChar = nChars = 0;
}
三、BufferedReader类API
1)读取1个或多个字节,返回一个字符,当读取到文件末尾时,返回-1:暂时看不懂实现细节,先了解作用
public int read() throws IOException{}
read()方法实例:结果与文件内容一致
public static void main(String[] args)
{
// 建立文件对象,
File file = new File("C:\\Users\\Administrator\\Desktop\\4.txt");
try
{
InputStreamReader reader = null;
BufferedReader bufferedReader = null;
try
{
// 构建InputStreamReader流对象并指定字符集
reader = new InputStreamReader(new FileInputStream(file),
"utf-8");
// 构建BufferedReader对象
bufferedReader = new BufferedReader(reader);
StringBuffer sb = new StringBuffer();
int n = 0;
while (n != -1)
{
n = bufferedReader.read();// 一次读取一个字符
char result = (char) n;
sb.append(result);
}
System.out.println(sb.toString());
}
finally
{
if(bufferedReader!=null)
{
reader.close();
bufferedReader.close();
}
}
}
catch (FileNotFoundException e)
{
System.out.println("文件不存在或者文件不可读或者文件是目录");
}
catch (IOException e)
{
System.out.println("读取过程存在异常");
}
}
2)将最多length个字符读入数组中,返回实际读入的字符个数,当读取到文件末尾时,返回-1,其本质是等于多次重复调用read()方法来获取多个字符
public int read(char[] cbuf, int off, int len) throws IOException{}
read(char[] cbuf, int off, int len)方法实例:结果比文件内容多出多个空格,因为读取字符数会大于数据的字符数
public static void main(String[] args)
{
File file = new File("C:\\Users\\Administrator\\Desktop\\4.txt");
try
{
InputStreamReader reader = null;
BufferedReader bufferedReader = null;
try
{
// 构建InputStreamReader流对象并指定字符集
reader = new InputStreamReader(new FileInputStream(file),
"utf-8");
// 构建BufferedReader对象,使用默认缓冲区大小
bufferedReader = new BufferedReader(reader);
char[] datas=new char[(int) file.length()]; //以文件字节长度设置字符数组,避免内容丢失,但会造成内存多余
int n = 0;
while (n != -1)
{
n = bufferedReader.read(datas,0,datas.length);// 读取字符数组长度个字符到数组中
}
3)读一行文字并返回该行字符,若读到文件末尾,则返回null:即当遇到换行符('\ n'),回车符('\ r')时会终止读取表示该行文字读取完毕且返回该行文字(不包含换行符和回车符)
public String readLine() throws IOException{}
readLine()方法实例: 结果与内容相比,失去了换行的格式,即所有内容都在一行
解决办法:
sb.append(readData).append("\r"); //添加换行符保证格式一样
public static void main(String[] args)
{
File file = new File("C:\\Users\\Administrator\\Desktop\\4.txt");
try
{
InputStreamReader reader = null;
BufferedReader bufferedReader = null;
try
{
// 构建InputStreamReader流对象并指定字符集
reader = new InputStreamReader(new FileInputStream(file),
"utf-8");
// 构建BufferedReader对象,使用默认缓冲区大小
bufferedReader = new BufferedReader(reader);
String readData="";
StringBuffer sb=new StringBuffer();
while (readData != null)
{
readData = bufferedReader.readLine();// 整行读取(但不包括终止符)
if(readData!=null){
sb.append(readData);
}
}
System.out.println(sb.toString());
}
finally
{
if(bufferedReader!=null)
{
reader.close();
bufferedReader.close();
}
}
}
catch (FileNotFoundException e)
{
System.out.println("文件不存在或者文件不可读或者文件是目录");
}
catch (IOException e)
{
System.out.println("读取过程存在异常");
}
}
四、BufferedReader类与InputStreamReader类比较
1、InputStreamReader中的文档说明提到过:为了获得最高效率,请考虑在BufferedReader中包装InputStreamReader
2、从源码实现角度理解BufferedReader类比InputStreamReader类效率高的原因是多了一个缓冲字符数组--此处未理解