黑马程序员技术交流社区
标题:
OutputStream.write(int b)方法的问题
[打印本页]
作者:
李栋梁
时间:
2012-11-25 21:05
标题:
OutputStream.write(int b)方法的问题
本帖最后由 李栋梁 于 2012-11-26 08:42 编辑
OutputStream.write(int b)
将指定的字节写入此输出流。write 的规定是:向输出流写入一个字节。
要写入的字节是参数b的八个低位。b 的24个高位将被忽略
。
这是什么意思的?
作者:
郝少普
时间:
2012-11-25 21:21
一般一个16位(双字节)的数据,比如 FF1A (16进制)那么高位字节就是FF,低位是1A如果是32位的数据,比如 3F68415B高位字(不是字节)是3F68低位字是415B右边是低位位,左边是高位 这个与操作系统有关
作者:
郝少普
时间:
2012-11-25 21:25
举个不恰当的例子,比如在win系统下 高地位对于内存而言 如 1A3F C23B 左边1A3F 是高位 右边 C23B 是低位
作者:
杨卫腾
时间:
2012-11-25 21:51
这样的意思是这样的,在设计的时候,不是还有一个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位。
以上是我自己的总结,希望对你有用。
作者:
李栋梁
时间:
2012-11-25 22:33
OutputStream的基本方法是write(int b)。该方法将介于0到255之间的整数看作变量,并将相应的字节写到一个输出流。该方法声明是个抽象方法,因为子类需要改变它以处理特定媒体。例如,ByteArrayOutputStream可以使用拷贝字节到其数组的纯Java代码来实现方法。但是,FileOutputStream就需要使用代码,此代码应该理解如何在主机平台上将数据写入文件。
注意:
尽管该方法把整形值作为变量,但是它实际上写入的是一个无符号字节。Java没有无符号字节数据类型,因此这里使用整型来代替。无符号字节和有符号字节之间的真正区别是编译器对它们的解释。二者都是由8位组成,并且当使用write(int b)将一个int写入到网络连接流时,只有8位数据传送。如果将一个超出0-255范围的int传给write(int b),则写入该数字的低位字节,而忽略余下的三个字节(大家都知道java的int是4个字节的,这里本质就是将int转换为byte)。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2