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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黄敏文 黑马帝   /  2011-9-1 20:33  /  2226 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

[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的,在想字节数组应该是在自动增长的,如果是又是如何增长的,字符数组是否也是会自动增长,其原理是否和字节数组一样

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

9 个回复

倒序浏览
呵呵,有一点首先要纠正下:这个问题,不是数组大小增长的问题的~

为了理解这个字节数组的作用,我们不妨先来看一下这段代码吧:[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 编辑 ]

评分

参与人数 1技术分 +3 收起 理由
admin + 3 不错,加分必须的!

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-9-1 21:56:35
藤椅
增长见识了
回复 使用道具 举报
黑马网友  发表于 2011-9-1 21:58:52
板凳
我是不是又说复杂了……:L
回复 使用道具 举报
黑马网友  发表于 2011-9-1 22:27:04
报纸
2楼果然高手~
回复 使用道具 举报
黑马网友  发表于 2011-9-1 22:35:33
地板

回复 板凳 的帖子

分析的很有逻辑性啊
回复 使用道具 举报
黑马网友  发表于 2011-9-1 22:49:55
7#
补充一下 byte[] buf = new byte[1024];  可以写为byte[] buf = new byte[fis.available];
回复 使用道具 举报
黑马网友  发表于 2011-9-1 23:47:31
8#

回复 7 # 的帖子

是有这么一方法,不过好像很多看到人用
回复 使用道具 举报
黑马网友  发表于 2011-9-3 00:07:31
9#
七楼的用法视频说过,但文档说得很含糊,并不一定一次就能刚好达到所续大小。特别在网络运输中,文档还说会出现类似堵塞现象。
回复 使用道具 举报
黑马网友  发表于 2011-9-5 10:35:02
10#
二楼适合当老师,很透彻,一看就懂了

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1 同意

查看全部评分

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