BufferedInputStream不行了头大了,老鸟们救命啊!

totddqq 2011-10-05 05:51:27
下面这段是书里想要证明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,对吗?
...全文
506 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
HaaHnju 2011-10-19
  • 打赏
  • 举报
回复
byte作用就是读取一个字节后,记录一下,转存到write里面, 就像
temp=a
a=b
b=temp
完成交换中的temp
fainfy 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 totddqq 的回复:]

引用 7 楼 fainfy 的回复:
public int read(byte[] b,
int off,
int len)
throws IOException从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。
此方法实现了 InputStream 类相应 read 方法的常规协定。另一个便捷之处在于,它将通过重复地调用底层流的 read 方法,尝试读取尽可能多……
[/Quote]

没必要这么纠结吗?如果你不提供一个缓冲区,数据怎么给你?你无法操作数据,读取了有什么意义?
totddqq 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 fainfy 的回复:]
public int read(byte[] b,
int off,
int len)
throws IOException从此字节输入流中给定偏移量处开始将各字节读取到指定的 byte 数组中。
此方法实现了 InputStream 类相应 read 方法的常规协定。另一个便捷之处在于,它将通过重复地调用底层流的 read 方法,尝试读取尽可能多的字节。这种迭代的 read……
[/Quote]
你好!缓冲区的原理我知道,我不明白或者说是模糊的是:BufferedInputStream所说的自带的缓冲区就是data?在每次使用时都需要我们自己申请出来?
fainfy 2011-10-06
  • 打赏
  • 举报
回复
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

把读到的字节数被存放于这个数组中,供使用(所以叫“目标缓冲区”)
totddqq 2011-10-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 huntor 的回复:]

public java.io.BufferedInputStream(java.io.InputStream);
public java.io.BufferedInputStream(java.io.InputStream, int);

参数类型是 InputStream,只要是InputStream的子类实例都可以,你还可以试试传一个 BufferedInputStrem实例进……
[/Quote]
哦哦,我去试试~
totddqq 2011-10-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zljjava 的回复:]

2)byte[] data = new byte[1];
....
while(bufferedInputStream.read(data) != -1) {
bufferedOutputStream.write(data);
}
--:bufferedInputStream每次都将数据读到内存也就是data中,然后bufferedOutputStream再把它写到
文件里。data就相当于一个缓冲区
[/Quote]
你好,谢谢你来回答我的问题。看了你的回答我有个疑问也许是我学的还不到位,但请你解释一下:BufferedInputStream不是说自带缓冲区得吗?那这个data他起到的作用也是缓冲区不就没有太大意义了吗?
zljjava 2011-10-05
  • 打赏
  • 举报
回复
1)实例化子类对象时,可以把父类对象作为参数传入其中吗?
例如:BufferedInputStream类是继承至FileInputStream类的,但是上述代码中在构建子类对象buffIn时
却把FileInputStream的对象,作为参数传入了其中!请解释。
--:这是API中规定的,你可以查查 “节点流和处理流”,处理流实例化的时候 需要一个节点流
2)byte[] data = new byte[1];
....
while(bufferedInputStream.read(data) != -1) {
bufferedOutputStream.write(data);
}
--:bufferedInputStream每次都将数据读到内存也就是data中,然后bufferedOutputStream再把它写到
文件里。data就相当于一个缓冲区
huntor 2011-10-05
  • 打赏
  • 举报
回复
public java.io.BufferedInputStream(java.io.InputStream);
public java.io.BufferedInputStream(java.io.InputStream, int);

参数类型是 InputStream,只要是InputStream的子类实例都可以,你还可以试试传一个 BufferedInputStrem实例进去。
totddqq 2011-10-05
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 fainfy 的回复:]

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

可以查询一下API。
[/Quote]
额...BufferedInputStream类是继承至FileInputStream类的对吧?
那BufferedInputStream bufferedInputStream =new BufferedInputStream();是一个对象吧?那
new FileInputStream(srcFile)也是一个对象吧?如果都是对象,那不就是把父类对象作为参数传入子类对象里了嘛...
fainfy 2011-10-05
  • 打赏
  • 举报
回复
1. 这只是一个装饰模式,其实就是聚合,传一个对象进去没有什么不对吧。这是两个完全不相关的对象。
2. bufferedInputStream.read(data) != -1把读出来的数据放到data缓冲区中,如果返回-1则表示读完了。

可以查询一下API。

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧