黑马程序员技术交流社区

标题: 数组大小增长问题 [打印本页]

作者: 黄敏文    时间: 2011-9-1 20:33
标题: 数组大小增长问题
[code=java]
public class CopyPic {
        public static void main(String[] args) throws Exception {
                FileInputStream fis = new FileInputStream("CopyPic.gif");
                FileOutputStream fos = new FileOutputStream("CopyPic_copy.gif");               
        
                byte[] buf = new byte[1024];
                int len = 0;
                while ((len = fis.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                }        
               
                fos.close();
               
        }
}
[/code]

在以上测试的时候,我把byte[] buf = new byte[1024]改写成byte[] buf = new byte[1],程序也是正常运行的,不过图片的大小是超过了1kb的,在想字节数组应该是在自动增长的,如果是又是如何增长的,字符数组是否也是会自动增长,其原理是否和字节数组一样
作者: 李叶    时间: 2011-9-1 21:23
呵呵,有一点首先要纠正下:这个问题,不是数组大小增长的问题的~

为了理解这个字节数组的作用,我们不妨先来看一下这段代码吧:[code=java]//代码1
int p = 0;                           //定义一个int变量p(4个字节大小)
while ((p = fis.read()) != -1) {     //通过fis将数据读取到p中
  fos.write(p);                      //通过fos将p中读取到的数据写出
}[/code]然后再来对比一下你程序中的这段代码:[code=java]//代码2
byte[] buf = new byte[1024];          //定义一个1024字节大小的数组buf
while ((len = fis.read(buf)) != -1) { //通过fis将数据读取到buf中(在此暂时忽略len的作用)
  fos.write(buf, 0, len);             //通过fos将buf中读取到的数据写出
}[/code]对比一下两段代码以及注释,你可以发现什么呢?
呵呵,很明显,你会发现:
在第一段代码中,fis每次都会向p中读取4个字节(也就是一个int的大小)
而第二段代码中,fis每次都会向buf中读取1024个字节
当p或者buf中读满的时候,fos就会将读取到的内容写出

所以,你对字节数组buf[]大小的定义,影响到的只是:
每当fis向内存中读满多少个字节的时候,fos就会将它们写出

所以,如果你这个buf[]定义的大小为1,那么每次fis只要向内存中读入1个字节,fos就会将这个字节写出
而如果你这个buf[]定义的大小为1024,那么每次fis向内存中读满1024个字节的时候,fos才会将这1024个字节写出
很明显,当你把buf[]的大小定义在一个较大的范围时,由于程序读写的频率降低了,所以程序的效率就会较高,对不对?

所以,buf[]这个字节数组,用专业术语来描述的话,它应当叫做“内存缓冲区

下面就给出对内存缓冲区的说明和作用吧:
当InputStream或OutputStream需要从外部IO设备读写数据的时候
可以首先将数据读入到内存中的一个指定大小的字节数组中
只有当该字节数组被存满时,才将字节数组中的数据一次性地写入外部IO设备中
这个在内存中的字节数组就是内存缓冲区
由于计算机访问内存的速度比计算机访问外部IO设备的速度快的多
因此使用内存缓冲区可以有效降低计算机对硬盘读写的次数,从而提高程序运行的效率

Tips:
如果当内存缓冲区中还没有读满的时候,fis就已经读到了文件的末尾的话,那应当怎么办呢?
答案还是一样的:通过自己的学习去寻找答案吧!~

[ 本帖最后由 李叶 于 2011-09-01  21:37 编辑 ]
作者: 匿名    时间: 2011-9-1 21:56
增长见识了
作者: 匿名    时间: 2011-9-1 21:58
我是不是又说复杂了……:L
作者: 匿名    时间: 2011-9-1 22:27
2楼果然高手~
作者: 匿名    时间: 2011-9-1 22:35
标题: 回复 板凳 的帖子
分析的很有逻辑性啊
作者: 匿名    时间: 2011-9-1 22:49
补充一下 byte[] buf = new byte[1024];  可以写为byte[] buf = new byte[fis.available];
作者: 匿名    时间: 2011-9-1 23:47
标题: 回复 7 # 的帖子
是有这么一方法,不过好像很多看到人用
作者: 匿名    时间: 2011-9-3 00:07
七楼的用法视频说过,但文档说得很含糊,并不一定一次就能刚好达到所续大小。特别在网络运输中,文档还说会出现类似堵塞现象。
作者: 匿名    时间: 2011-9-5 10:35
二楼适合当老师,很透彻,一看就懂了




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