自定义包装类并不能成功拷贝文件的原因分析

仿BufferedInputStream自定义包装类MyBufferedInputStream如下:

class MyBufferedInputStream {
	private InputStream in;
	private byte[] buf = new byte[1024];
	private int pos = 0, count = 0;

	MyBufferedInputStream(InputStream in) {
		this.in = in;
	}
	public int myRead() throws IOException {
		if (count == 0) {
			count = in.read(buf);
			pos=0;
			if(count<0)
				return -1;
			byte b = buf[pos];
			count--;
			pos++;
			return b;
		} else if (count > 0) {
			byte b=buf[pos];
			count--;
			pos++;
			return b;
		}
		return -1;
	}
	public void myClose()throws IOException{
		in.close();
	}
}

public class CopyMp3 {
	public static void main(String[] args) throws IOException {
		MyBufferedInputStream bis=new MyBufferedInputStream(new FileInputStream("dream.mp4"));
		BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("dream_copy.mp4"));
		int ch=0;
		int num=0;
		while((ch=bis.myRead())!=-1){
			bos.write(ch);
			num++;
		}
		bis.myClose();
		bos.close();
}
测试发现并不能拷贝文件,从语法跟逻辑上貌似都找不到问题,但是仔细观察会发现,自定义类的myRead()方法要求返回int类型,而此函数的return b返回的b却是byte类型。这两个类型的区别byte是八位,而int是32位。因为在计算机内部,数据是由0和1组成,有可能出现11111111111000000101001010连续为1或0的情况,当byte类型的b读取一个字节时,如果读到的是1111-1111,那么翻译成十进制就是-1,即使由byte升级为int类型,也是-1,所以在while循环的时候就会停止下来。
解决方案如下:
修改前byte型-1为11111111升级为int型后补1变为11111111-11111111-11111111-11111111,现在如果把补1变为补0,则结果成了00000000-00000000-00000000-11111111,就不是-1了,而是255了,这样就实现了既保住原数据也避免了-1的情况。不要担心提升之后数据量增加,在read读到32位之后,write方法只会讲低8位写入文件,因此前面补的0也就不会写入文件了,拷贝后的文件就与原文件完全相同了。实现补0效果的方法是与运算:b&0xff或者b&255。本题中在所有return b的地方都做如下修改return b&0xff就行了


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值