下面这段是书里想要证明BufferedInputStream类是自带缓冲区的代码(代码内容是把一个文件里的内容复制到另一个文件里),小弟是自学的所以看了以后有些地方百思不得其解,查来查去头都楞了特请各位老手帮忙解惑。
package onlyfun.caterpillar;
 
import java.io.*;
 
public class BufferedStreamDemo {
    public static void main(String[] args) {
        try {
            byte[] data = new byte[1];             File srcFile = new File(args[0]); 
            File desFile = new File(args[1]);             BufferedInputStream bufferedInputStream = 
                new BufferedInputStream(
                         new FileInputStream(srcFile)); 
            BufferedOutputStream bufferedOutputStream = 
                new BufferedOutputStream(
                         new FileOutputStream(desFile));
 
            System.out.println("复制文件:" + 
                             srcFile.length() + "字节");            while(bufferedInputStream.read(data) != -1) { 
                bufferedOutputStream.write(data); 
            }
            
            // 将缓冲区中的数据全部写出 
            bufferedOutputStream.flush();
 
            // 关闭流 
 
            bufferedInputStream.close(); 
            bufferedOutputStream.close();             System.out.println("复制完成"); 
        } 
        catch(ArrayIndexOutOfBoundsException e) { 
            System.out.println(
                    "using: java UseFileStream src des"); 
            e.printStackTrace(); 
        } 
        catch(IOException e) { 
            e.printStackTrace(); 
        } 
    }
}提问:(1)实例化子类对象时,可以把父类对象作为参数传入其中吗?
           例如:BufferedInputStream类是继承至FileInputStream类的,但是上述代码中在构建子类对象buffIn时
           却把FileInputStream的对象,作为参数传入了其中!请解释。
      (2) byte[] data = new byte[1];
            ....
             while(bufferedInputStream.read(data) != -1) { 
                bufferedOutputStream.write(data); 
            }
           这两句是什么意思?data是外部的另申请的缓冲区吗?他的存在是为了证明:整个过程中起到缓冲作用的的是
           BufferedInputStream内部自带的缓冲区而不是外部申请的data,对吗?

解决方案 »

  1.   

    1. 这只是一个装饰模式,其实就是聚合,传一个对象进去没有什么不对吧。这是两个完全不相关的对象。
    2. bufferedInputStream.read(data) != -1把读出来的数据放到data缓冲区中,如果返回-1则表示读完了。可以查询一下API。
      

  2.   

    额...BufferedInputStream类是继承至FileInputStream类的对吧?
    那BufferedInputStream bufferedInputStream =new BufferedInputStream();是一个对象吧?那
    new FileInputStream(srcFile)也是一个对象吧?如果都是对象,那不就是把父类对象作为参数传入子类对象里了嘛...
      

  3.   

      public java.io.BufferedInputStream(java.io.InputStream);
      public java.io.BufferedInputStream(java.io.InputStream, int);参数类型是 InputStream,只要是InputStream的子类实例都可以,你还可以试试传一个 BufferedInputStrem实例进去。
      

  4.   

    1)实例化子类对象时,可以把父类对象作为参数传入其中吗?
      例如:BufferedInputStream类是继承至FileInputStream类的,但是上述代码中在构建子类对象buffIn时
      却把FileInputStream的对象,作为参数传入了其中!请解释。
    --:这是API中规定的,你可以查查 “节点流和处理流”,处理流实例化的时候 需要一个节点流
     2)byte[] data = new byte[1];
      ....
      while(bufferedInputStream.read(data) != -1) {  
      bufferedOutputStream.write(data);  
      }
    --:bufferedInputStream每次都将数据读到内存也就是data中,然后bufferedOutputStream再把它写到
         文件里。data就相当于一个缓冲区
      

  5.   

    你好,谢谢你来回答我的问题。看了你的回答我有个疑问也许是我学的还不到位,但请你解释一下:BufferedInputStream不是说自带缓冲区得吗?那这个data他起到的作用也是缓冲区不就没有太大意义了吗?
      

  6.   

    public int read(byte[] b,
                    int off,
                    int len)
             throws IOException从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。 
    此方法实现了 InputStream 类相应 read 方法的常规协定。另一个便捷之处在于,它将通过重复地调用底层流的 read 方法,尝试读取尽可能多的字节。这种迭代的 read 会一直继续下去,直到满足以下条件之一: 已经读取了指定的字节数, 
    底层流的 read 方法返回 -1,指示文件末尾(end-of-file),或者 
    底层流的 available 方法返回 0,指示将阻塞后续的输入请求。 
    如果第一次对底层流调用 read 返回 -1(指示文件末尾),则此方法返回 -1。否则此方法返回实际读取的字节数。 
    鼓励(但不是必须)此类的各个子类以相同的方式尝试读取尽可能多的字节。 
    覆盖:
    类 FilterInputStream 中的 read
    参数:
    b - 目标缓冲区。
    off - 开始存储字节处的偏移量。
    len - 要读取的最大字节数。 
    返回:
    读取的字节数;如果已到达流末尾,则返回 -1。 
    抛出: 
    IOException - 如果已经调用其 close() 方法关闭了此输入流,或者发生 I/O 错误。
    另请参见:
    FilterInputStream.in把读到的字节数被存放于这个数组中,供使用(所以叫“目标缓冲区”)
      

  7.   

    你好!缓冲区的原理我知道,我不明白或者说是模糊的是:BufferedInputStream所说的自带的缓冲区就是data?在每次使用时都需要我们自己申请出来?
      

  8.   

    byte作用就是读取一个字节后,记录一下,转存到write里面, 就像
    temp=a
    a=b
    b=temp
    完成交换中的temp