黑马程序员技术交流社区

标题: 为什么自定义数组拷贝时要传入数组的长度? [打印本页]

作者: 袁泽宇    时间: 2011-12-22 09:18
标题: 为什么自定义数组拷贝时要传入数组的长度?
本帖最后由 袁泽宇 于 2011-12-22 10:36 编辑

        FileInputStream fis = new FileInputStream("Adele - Rolling in the Deep.mp3");

        FileOutputStream fos= new FileOutputStream("dest.mp3");
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1)
                fos.write(buffer, 0, len);
               
        fis.close();
        fos.close();

        为什么要传入数组的长度呢?
        传入len,是从数组的第一个拷贝到最后一个,那直接传入buffer不就行了吗?

作者: 刘基军    时间: 2011-12-22 09:30
1.文件数据本身就小于buffer数组大小,
2.文件数据本身大于buffer数组大小,但最后一次读取的数据小于buffer数组大小
以上两种情况,所以需要使用:fos.write(buffer, 0, len);

作者: 1253431283    时间: 2011-12-22 09:34
1数组对象是固定的,所以要先申明数组的长度,否则语法不通过
作者: 袁泽宇    时间: 2011-12-22 09:37
1253431283 发表于 2011-12-22 09:34
1数组对象是固定的,所以要先申明数组的长度,否则语法不通过

语法通过了 呵呵   还能运行
作者: 陈帅雷    时间: 2011-12-22 09:37
fos.write(buffer);也可以,但是,如果有一次你读了4个字符进buffer数组,如果你用fos.write(buffer);就会把1024个字符全写入文件,这个时候真正有效的字符就4个,用fos.write(buffer, 0, len);写入文件的是buffer数组中len长度个字符,就是4个。所以要用fos.write(buffer, 0, len);一次读到几个字符就写入几个字符。

作者: 1253431283    时间: 2011-12-22 09:41
这怎么回事,我用eclipse不让通过
作者: 杨强    时间: 2011-12-22 09:43
传入len,是从数组的第一个拷贝到最后一个,那直接传入buffer不就行了吗?
len是fis.read(buffer) 是read出的个数 存入buffer  也就是len是现在buffer中字节的个数
作者: 袁泽宇    时间: 2011-12-22 10:11
我明白了。
倒数第二次读取时能把倒数第三次的数据全部覆盖,
倒数第一次读取时的数据长度可能没有数组长度长,所以不能全部覆盖倒数第二次的数据,只能覆盖前半部分的数据。
所以如果不传入len,在读取最后一组数据时会多读到倒数第二组的后半部分的数据。

不知道大家明白了吗   呵呵{:soso__10017666544099281011_3:}
作者: 周敏2011nc    时间: 2011-12-22 10:13
使用write(buffer, 0, len)是解决数据多余的问题:
在你每read(byte[] buffer)一次后,它就将一定长度的数据写入到了buffer中,它的长度取决于以下情况 :
Read(char[] chr)方法从指定的文件读chr.length到chr字符数组中,如果chr.length大于文件中的字符长度,则数据全部放在chr数组中;如果chr.length < 文件中字符长度,读一次,就写人chr.length的数据,下次度接着上次读到的末尾继续读,并将第上一次写入的数据覆盖掉,如果再读到某次时,要读入的文件的数据长度〈 str.length,就依次覆盖,没有覆盖到的仍是上一次覆盖后的数据。
len = fis.read(buffer)返回的是每次读入的实际长度,如果不指定len,它会将上一次没被覆盖掉的数据写入,造成数据多余。
作者: 杨扬    时间: 2011-12-22 10:19
本帖最后由 杨扬 于 2011-12-22 10:22 编辑

fos.write(buffer, 0, len);
是一次读取并写入buffer的长度..从头开始写.如果长度不够.就写到len(也就是结尾处).

如果写成这样  
while ((len = fis.read()) != -1)
       fos.write(len);
那么就是读一个写一个..就失去了效率.

你可以在复制前后加上System.currentTimeMillis()方法来计算时间看看速度.




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