这样的意思是这样的,在设计的时候,不是还有一个java.io.InputStream.read(); 这个
方法是返回一个字节数据,但是,用int 类型的来接收,这样就会将其变成是int类型的,
这是为了避免一个特殊的情况: 如下所示:
这是将字节数据进行了类型的提升,使之变成了int类型。从 byte类型变成 int类型,
这就是为了改变在读取字节流中数据的时候所遇到的特殊情况,比如要读取的八个二进制位都是1的情况,这个数据就是-1了,-1提升为int类型的时候还是-1,这就是漏洞了。
要解决这个漏洞所以我们给byte &255,这样就会避免掉-1的情况了。下面是我模拟的这个过程,这个过程的实现是这样的,我定义了一个自己的缓冲区读取类,模拟BufferedInputStream.
我的图解过程是这样的:
byte:11111111 表示的是-1;
int : 11111111-11111111-11111111-11111111 表示的也是-1;
& 11111111
00000000-00000000-00000000-11111111
---------------------------------------------------------------------------------
00000000-00000000-00000000-11111111
所以应该在前边的24个二进制位都应该变成0,才能行。那我们就给与上255。这是我模拟的过程:
class Test
{ public static void main(String[] args) throws Exception
{ //获取这个复制过程中消耗的时间
long start = System.currentTimeMillis();
method();
long end = System.currentTimeMillis();
System.out.println("time="+(end-start)+"毫秒");
}
public static void method() throws Exception {
MyBufferedInputStream bufis = new MyBufferedInputStream(new
FileInputStream("C:\\Users\\杨卫腾\\Desktop\\1.mp3"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\杨卫腾\\Desktop\\2.mp3"));
int data = 0;
while((data= bufis.myRead())!=-1){
bufos.write(data);
bufos.flush();
}
bufis.myClose();
bufos.close();
}
}
class MyBufferedInputStream
{
private InputStream in;
private byte[] buf = new byte[1024];
private int pos = 0,count = 0;
MyBufferedInputStream(InputStream in){
this.in = in;
}
//如果没有给b &255,这个时候复制文件的时候,复制了一个部分就停止了。
public int myRead() throws IOException {
//通过in对象读取硬盘上的数据并存储在buf中
if(count==0){
count = in.read(buf);
if(count<0)
return -1;
pos = 0;
byte b = buf[pos];
pos++;
count--;
return b&255;
}else if(count>0){
byte b = buf[pos];
pos++;
count--;
return b&255;
}
return -1;
}
public void myClose() throws IOException {
in.close();
}
}
以上就是为什么writie()方法使用写一个int类型数据。
要是你不读去文件中的二进制数据, 自己传进去一个int类型的数据(大于255) 的,
那么你的数据将会被舍弃其他24位。
以上是我自己的总结,希望对你有用。 |