------- android培训、java培训、期待与您交流! ----------
缓冲区简介:
Io流中的缓冲区分为两类,一类是字符缓冲区:BufferedReader、BufferedWriter。一类是字节缓冲区:BufferedInputStream、
BufferedOutputStream。但是它们的作用是相同的,都是为了提高读写效率而存在的。
因为IO中普通的read与write方法,虽然也可以达到我们的目的。但是它们的效率极低,它们的工作原理就是在硬盘中读一个字符(或字节)在写一个字符(或字节)。不但效率低下,而且比较伤害硬盘。所以我们要用到缓冲区,它们的关系在毕老师在视频中有一个很恰当的比喻就是———喝水 。前者如同一滴一滴喝水,而后者是用水杯接满一杯再喝。
缓冲区原理:
我们知道了缓冲区可以提高效率,但是它的原理是什么呢,它是用过什么来提高效率的呢?下面我们来用两端代码来演示一下字符缓冲区与字节缓冲区的操作原理。
1.字符缓冲区BufferedReader
import java.io.*; <span style="white-space:pre"> </span>
class BufferedReaderDemo
{
public static void main(String[] args) throws Exception
{
FileReader fr = new FileReader("BIST.java");<span style="white-space:pre"> </span>//建立文件读取流读一个本地文件
MyBufferedReaderDemo mbur = new MyBufferedReaderDemo(fr);<span style="white-space:pre"> </span>//添加到缓冲区
String line =null;
while((line=mbur.myReadLine())!=null)<span style="white-space:pre"> </span>//打印
{
System.out.println(line);
}
}
}
class MyBufferedReaderDemo<span style="white-space:pre"> </span>//自定义一个字符缓冲区
{<span style="white-space:pre"> </span>
private Reader r;<span style="white-space:pre"> </span>//私有成员变量Reader,因为要传递进来Read的子类
MyBufferedReaderDemo(Reader r)<span style="white-space:pre"> </span>//构造函数
{
this.r = r;
}
public String myReadLine() throws Exception <span style="white-space:pre"> </span>//主要方法ReadLine
{
int num = 0;<span style="white-space:pre"> </span>//定义一个变量用来接受read方法返回的值
StringBuilder sb = new StringBuilder();<span style="white-space:pre"> </span>//建立一个字符串缓冲区用来存我们每次读到的字符
while((num=r.read())!=-1)<span style="white-space:pre"> </span>//建立循环直到文件末尾
{
if (num=='\r')<span style="white-space:pre"> </span>//进行判断如果读到的是'\r'则继续执行循环
continue;
if(num=='\n')<span style="white-space:pre"> </span>//如果读到'\n'说明是行末尾,把缓冲区内的字符tostring返回字符串
return sb.toString();
else
sb.append((char)num);<span style="white-space:pre"> </span>//把得到的字符添加到缓冲区注意需要强制转换
}
if(sb.length()!=0)<span style="white-space:pre"> </span>//另外加判断如果字符缓冲区中有值则返回,因为有可能文件末尾并没有'\n'
return sb.toString();
return null;<span style="white-space:pre"> </span>
}
}
2.字节缓冲区BufferedInputStrea
import java.io.*;
class BufferedReaderDemo
{
public static void main(String[] args) throws Exception
{
FileInputStream fis = new FileInputStream("BIST.java");
MyBufferedInputStream mbfi = new MyBufferedInputStream(fis);
int by = 0;<span style="white-space:pre"> </span>
while((by=mbfi.read())!=-1)<span style="white-space:pre"> </span>//建立循环读取
{
System.out.print((char)by);
}
}
}
class MyBufferedInputStream
{
private InputStream is;<span style="white-space:pre"> </span>//私有一个成员变量为了接受InputStream子类
byte [] buf = new byte[1024];<span style="white-space:pre"> </span>//建立一个数组充当缓冲区长度为1024
private int count,pos;<span style="white-space:pre"> </span>//定义一个计数器变量,一个标记变量
MyBufferedInputStream(InputStream is) <span style="white-space:pre"> </span>
{
this.is = is;
}
public int read()throws Exception<span style="white-space:pre"> </span>//主要方法
{
if(count==0)<span style="white-space:pre"> </span>//如果count等于0则取一批数据
{
count =is.read(buf);<span style="white-space:pre"> </span>//用count记录取到的数据长度
if(count<0)<span style="white-space:pre"> </span>//如果count小于0则返回-1
return -1;
pos=0;<span style="white-space:pre"> </span>//初始化标记
byte b = buf[pos];<span style="white-space:pre"> </span>//把数组中的元素赋给byte变量
pos++;<span style="white-space:pre"> </span>//因为取了一个元素所以pos自增,count自减。
count--;<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>
return b&255;<span style="white-space:pre"> </span>//返回b&255是为了防止出现11111111的情况所以我们返回值是int类型
}<span style="white-space:pre"> </span>
else if(count>0)<span style="white-space:pre"> </span>//如果count>0
{<span style="white-space:pre"> </span>
byte b=buf[pos];<span style="white-space:pre"> </span>//取元素
pos++;<span style="white-space:pre"> </span>//pos自增
count--;<span style="white-space:pre"> </span>//count自减
return b&255;<span style="white-space:pre"> </span>//返回值
}
return -1;
}
}