/*IO_MyBufferedInputStream*/
/*
需求:模拟字节读取流缓冲区
思路:字节读取流缓冲区是字节流在硬盘上读取一批数据然后存到数组中,计数器记录
住当前批次数据的个数,然后数组再通过指针来读取数据,每读取一个数据,计数器就
减一,直到读完当前批次的数据,缓冲区数组再次使用字节流在硬盘上读取一批数据,
以此类推,直到字节流把目标地址中的硬盘数据读完为止
步骤:
①自定义字节读取缓冲区类MyBufferedInputStream,初始化该类时接收一个字节流对象
FileInputStream in;
②定义计数器变量count和指针变量post
③定义接收字符的数组buf
④定义关闭资源对象myclose
*/
import java.io.*;
class MyBufferedInputStream
{
FileInputStream in; //定义字节流对象的引用
int count = 0; //定义计数器
int post = 0; //定义指针
byte b = 0; //定义取出数组中数据的变量
byte[] buf = new byte[1024]; //定义缓存数组
MyBufferedInputStream(FileInputStream in)
{
this.in = in; //接收一个字节流对象
}
public int myRead() throws IOException
{
if (count ==0) //如果计数器为0则说明缓存数组中没有数据,这时接收一批数据
{
count = in.read(buf); //接收一批数据存入到缓存数组中
post = 0; //指针为0,这里强调一下,如果把指针重置为0的话,那么读取下一批次的时候,指针会越界
b = buf[post]; //读取数据
count--; //计数器自减,因为读取出一个元素,元素个数就会减少一个,直到把数组中的元素读完,才接收下一批次的数据
post++; //指针累加,读取数组中的数据
return b&255; //这里是(int) b强制转换了byte型的b
/*
为什么把byte型的b 强制转换成int型的?
因为return 返回的是 int类型的
为什么不把返回值定义成byte型的呢?
因为如果文件读取到末尾返回的是-1,这个-1 是int型的
那为什么又要让强制转换后的b &255呢?
mp3的字节二进制文件有可能是1111-1111这样排列的,而这个值转换成十进制后是-1
byte型(8位):1111-1111(-1)
强制转换后
int型(32位):1111-1111 1111-1111 1111-11111 111-1111 (-1)
return返回-1程序就不会读取字符缓冲区的数据了,但是硬盘上的数据没有读完
这时我们就让提升后的int型 b与上255
1111-1111 1111-1111 1111-1111 1111-1111
&0000-0000 0000-0000 0000-0000 1111-1111
————————————————————
0000-0000 0000-0000 0000-0000 1111-1111 ——>保留的是后8位,也就是byte型数据的值,
write写入时会自动将int型强制转换成byte型,到时候保留的就是,数组缓冲区中byte型的数据
*/
}
else if (count >0) //计数器不为0,说明数组中的元素没有完全取出,继续取出操作
{
b = buf[post];
count--;
post++;
return b&0xFF;
}
else
return -1; //如果read() 返回-1,则硬盘上的数据已经读取完毕,返回-1
}
public void myClose() throws IOException
{
in.close(); //关闭资源
}
}
class MyBufferedInputStreamDemo
{
public static void main(String[] args)
{
long start = System.currentTimeMillis();
CopyMp3();
long end = System.currentTimeMillis();
System.out.println(end-start+"毫秒");
}
public static void CopyMp3()
{
MyBufferedInputStream mbis = null;
BufferedOutputStream bos = null;
int len = 0; //定义为int型,不能定义成byte,因为要接收文件读取结束的-1,而-1 是int 型的
try
{
mbis = new MyBufferedInputStream(new FileInputStream("d:\\1.mp3")); //使用自定义的缓冲区读取数据,传入一个字节流对象
bos = new BufferedOutputStream(new FileOutputStream("d:\\3.mp3"));
while ((len = mbis.myRead()) != -1)
{
bos.write(len);
}
}
catch (IOException e)
{
System.out.println(e.toString());
}
finally
{
try
{
if(mbis != null)
mbis.myClose();
}
catch (IOException e)
{
System.out.println(e.toString());
}
try
{
if(bos != null)
bos.close();
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
}
}