A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李栋梁 中级黑马   /  2012-11-25 21:05  /  5488 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李栋梁 于 2012-11-26 08:42 编辑

OutputStream.write(int b)将指定的字节写入此输出流。write 的规定是:向输出流写入一个字节。要写入的字节是参数b的八个低位。b 的24个高位将被忽略 这是什么意思的?

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

4 个回复

正序浏览
这样的意思是这样的,在设计的时候,不是还有一个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位。

以上是我自己的总结,希望对你有用。

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

回复 使用道具 举报
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)。
回复 使用道具 举报
举个不恰当的例子,比如在win系统下 高地位对于内存而言 如  1A3F C23B  左边1A3F 是高位   右边  C23B 是低位
回复 使用道具 举报
一般一个16位(双字节)的数据,比如 FF1A  (16进制)那么高位字节就是FF,低位是1A如果是32位的数据,比如  3F68415B高位字(不是字节)是3F68低位字是415B右边是低位位,左边是高位   这个与操作系统有关

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马