java 添加至字节流缓存中_Java基础知识IO流(字节流的缓存区并自定义)

字节流缓存区

自定义字节流缓存区

read()和write()方法的特点

字节流缓存区

字节流也有缓存区

BufferedInputStream

BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。

BufferedOutputStream

该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

缓存原理

以将MP3文件复制到别处为例:

BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("music.mp3"));

bufis.read();

MP3文件存放在硬盘上,文件内都是字节数据。当bufis.read();时,不是直接在硬盘上读取字节数据,而是先用FileInputStream()的read(byte[])方法读取字节缓存到内存的缓冲区(字节数组)中,并返回读取的字节数,定义计数器,初始值就是该字节数,再从缓冲区(字节数组)取出数据,读取数据时定义一个指针,一个一个地读取,每 读取一个,指针指向下一个,同时计数器减1,直到减到0时,说明本组数据读完,再读下一组数据到缓存区中(字节数组),直到取到的数据个数是-1时,说明读取完毕。简言之:缓冲区的思想就是从硬盘上获取一批数据到内存缓冲区中,一个一个读取,然后再获取一批数据一个个读取,这样效率比较高。

自定义字节流缓存区

已知缓存原理,自定义字节流的缓冲区:

1.定义缓冲区

2.定义计数器(初始值是0,myRead()方法中当判断到count=0时,将count数值设置为读取到字节数组中的字节数)

3.定义指针 (初始值是0)

4.自定义myRead()方法,读取一个字节,返回int型数据。

5.自定义myClose()方法。

import java.io.*;

class MyBufIsTest

{

public static void main(String[] args) throws IOException

{

long start = System.currentTimeMillis();

copy_2();

long end = System.currentTimeMillis();

System.out.println((end-start)+"毫秒");

}

public static void copy_2()throws IOException

{

MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("testCopyJpg.jpg"));

BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("testCopyJpg2.jpg"));

int by = 0;

//System.out.println("第一个字节:"+bufis.myRead());

while((by=bufis.myRead())!=-1)

{

bufos.write(by);

}

bufos.close();

bufis.myClose();

}

}

class MyBufferedInputStream

{

private InputStream is=null;

private int count=0;

private int pos=0;

private byte[] buf=new byte[1024];

MyBufferedInputStream(InputStream is)

{

this.is=is;

}

//一次读一个字节,从缓存区(字节数组)获取

public int myRead()throws IOException

{

//通过is对象读取硬盘上的数据,并存储在buf中,即进行缓存。

//先判断count是否为0,若为零表示初次读取或者数组中的字节已读完,那么读取一批数据到字节数组中。

//再判断此时count是否小于0,若小于0,表示硬盘上的数据已读完,返回-1

//然后pos=0,从数组的第一个数据开始读

//读完后pos++,count--

//将读取的byte类型的b与0xff进行&运算:之所以没有直接强转int,因为强转时,前面添加1,那么前8位为-1,会误以为读取完毕,与0xff&运算的话,

//前面添加0,就避免了这种情况。

//若count大于0,说明数组中的数据还未读完,继续读取数据,并count--,pos++,同样b&0xff

//若count是否小于0,表示硬盘上的数据已读完,返回-1。

if(count==0)

{

count=is.read(buf);

if(count<0)

return -1;

pos=0;

byte b=buf[pos];

pos++;

count--;

return b&0xff;

}

else if(count>0)

{

byte b=buf[pos];

pos++;

count--;

return b&0xff;

}

return -1;

}

public void myClose() throws IOException

{

is.close();

}

}

read()和write()方法的特点

read()方法的返回值类型是int类型,通过与0xff进行&操作,而不是强转为int类型,是为了在前面添0,即保留了原字节数据不变,又避免了-1的出现。

write(int b)方法会强制将int类型的参数b强转危byte类型,只保留最低8位。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值