黑马程序员技术交流社区

标题: 提问:缓冲区的write方法疑惑 [打印本页]

作者: filter    时间: 2012-12-23 14:45
标题: 提问:缓冲区的write方法疑惑
本帖最后由 李志阳 于 2012-12-26 17:09 编辑
  1. /*
  2. 演示MP3的复制,通过缓冲区

  3. BufferedOutputStream
  4. BufferedInputStream
  5. */

  6. import java.io.*;
  7. class  CopyMp3
  8. {
  9.         public static void main(String[] args) throws IOException
  10.         {        
  11.                 long start = System.currentTimeMillis();
  12.                 copyMusic();
  13.                 long end = System.currentTimeMillis();

  14.                 System.out.println((end-start)+"毫秒");
  15.         }
  16.         public static void copyMusic() throws IOException
  17.         {
  18.                 BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("C:\\Documents and Settings\\Administrator\\桌面\\原本.mp3"));
  19.                 BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("F:\\张学友.mp3"));

  20.                 int by = 0;

  21.                 while ((by = bufis.read()) != -1)
  22.                 {
  23.                         bufos.write(by);
  24.                 }
  25.                 bufis.close();
  26.                 bufos.close();
  27.         }
  28. }
复制代码

变量by明明是个整数,在这个程序里面怎么能实现读取和写入操作呢?不是应该写入的是字节的吗,by应该是个字节类型变量啊?

作者: 翁鹏    时间: 2012-12-23 15:03
这个问题毕老师第19天的视频有详细的讲解。

其实,从硬盘读取的确实是的字节,但是为了避免-1的发生,就把读取的字节提升为int型,其实有效的数据还是最低的8位,还是一个字节。

写的时候也是只写最低的8位

作者: 焦健    时间: 2012-12-23 15:04
Reader类中的read方法读取单个字符。返回作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1
read内部也是通过字节数组实现的,附上源文件代码
public int read() throws IOException {
        char cb[] = new char[1];
        if (read(cb, 0, 1) == -1)
            return -1;
        else
            return cb[0];
    }

public void write(int c)写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。
这个同样附上源码,在内部将int类型强转为char类型存入然后再打印出去,相信你会看明白的。
public void write(int c) throws IOException {
        synchronized (lock) {
            if (writeBuffer == null){
                writeBuffer = new char[writeBufferSize];
            }
            writeBuffer[0] = (char) c;
            write(writeBuffer, 0, 1);
        }
    }

作者: 黄锦成    时间: 2012-12-24 11:35
这个我以前也是有些疑惑的!不过昨晚重看了张孝祥老师的io视频,终于解决了这个问题。
先明确一点:流结尾是-1表示的
byte用int来表示,范围在0~255;byte范围在-128~127
问题来了:如果返回类型是byte,当返回-1时,这个-1是表示结尾,还是读取文本返回的数据-1呢?
解决办法:返回类型是int,读取的数据都在0~255范围之间,根本不可能出现-1,只有到了流的结尾,才会出现-1,这就解决了上面的问题。
这也表明了设计者当初设计的时候考虑得有多么细致了。这个也是值得我们学习的
作者: 清水    时间: 2012-12-24 11:44
前面答得很好! read返回的时候把byte&255返回int型,就是为了避免发生-1的情况。
write传入int型,只保留最后8位,也很高明。
作者: 刘渝灵    时间: 2012-12-24 15:47
黄锦成 发表于 2012-12-24 11:35
这个我以前也是有些疑惑的!不过昨晚重看了张孝祥老师的io视频,终于解决了这个问题。
先明确一点:流结尾 ...

如果返回类型是byte,当返回-1时,这个-1是表示结尾,还是读取文本返回的数据-1呢?

既然如此 那为什么不返回 比如 -129 呢?
作者: 刘渝灵    时间: 2012-12-24 15:48
刘渝灵 发表于 2012-12-24 15:47
如果返回类型是byte,当返回-1时,这个-1是表示结尾,还是读取文本返回的数据-1呢?

既然如此 那为什么 ...

。。-129 超出 byte 范围了
作者: 黄锦成    时间: 2012-12-24 16:28
刘渝灵 发表于 2012-12-24 15:47
如果返回类型是byte,当返回-1时,这个-1是表示结尾,还是读取文本返回的数据-1呢?

既然如此 那为什么 ...

这个超出了byte的范围了,byte的范围是-128~127
作者: 刘渝灵    时间: 2012-12-24 16:46
黄锦成 发表于 2012-12-24 16:28
这个超出了byte的范围了,byte的范围是-128~127

我想问下 FilterInputStream read方法返回一个 0 到 255 范围内的 int 字节值。
读取的是byte类型 也即范围 -128~127 这个是怎么提升到 0~255的 我一分析 补码 什么的 就浆糊了
作者: 黄锦成    时间: 2012-12-24 16:51
刘渝灵 发表于 2012-12-24 16:46
我想问下 FilterInputStream read方法返回一个 0 到 255 范围内的 int 字节值。
读取的是byte类型 也即范 ...

这个就是方法内部的事了,这个二进制操作挺麻烦的,我就记得这个。你可以看jdk源码了解的,或百度之类的




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2