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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 严明 初级黑马   /  2012-6-26 18:31  /  8735 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 严明 于 2012-6-27 00:00 编辑

在毕老师复制mp3文件的视频里,有这么一段代码,声明mp3文件比1024大

FileInputStream fis = newFileInputStream("a.mp3");

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

               
        fis.close();
        fos.close();
我将红色部分改成:
fos.write(buffer);   这样也能复制成功
那么write()的时候为什么传入数组的长度呢? 视频中好像是这样说的:
最后一次将字节装入字节数组中, 但是最后一次读取的字节总数 并没有1024 ,
所以最后一次读取的数据会覆盖 倒数第二次装在数组中的数据, 但是它无法全部覆盖,那么 就会覆盖数组的前半部分了 数组的后半部分仍然是倒数第二次的数据.

我用fos.write(buffer) 这样是将最后一次数组里面的全部数据(包括最后一此存在数组里面前半部分的 和 倒数第二次保留在数组后半部分的)都写入文件copy.mp3
按理说这种方法复制出来的文件字节总数一定会比原文件大, 但是结果是跟原文件是一样大的,why?



6 个回复

倒序浏览
应该是你复制的文件小于1024字节或者是你复制的文件正好是1024字节的整数倍。
回复 使用道具 举报
本帖最后由 邱国 于 2012-6-26 19:30 编辑

一个个回答:
仔细看API文档,下面是对write(byte[] b)的说明:
write
public void write(byte[] b)
           throws IOException
将 b.length 个字节从指定的 byte 数组写入此输出流。write(b) 的常规协定是:应该与调用 write(b, 0, b.length) 的效果完全相同

public void write(byte[] b,
                  int off,
                  int len)
           throws IOException将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。write(b, off, len) 的常规协定是:将数组 b 中的某些字节按顺序写入输出流;元素 b[off] 是此操作写入的第一个字节,b[off+len-1] 是此操作写入的最后一个字节。

这就解释了你的问题,其实你用wtite(buffer)和write(buffer, 0,len);都是一样的,之所以建议用后面那个write方法,其实是避免如果文件大小非常少的话,用后面的方法可以理论上避免了传入   把数组后面没用到的内存空间。     只传入0到length的部分,没传入数组后面没用的部分




评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
大小是不一样的,fos.write(buf)比原文件大

左图是fos.write(buf),右图为fos.write(buf,0,len)复制文件,和原文件大小一样

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 王莹 于 2012-6-26 19:43 编辑

调用的read方法,有两种形式,一种是read(byte [] b),一种是read(byte[] b,int off,int len),对应到你的程序中就是read(buffer)和read(buffer,0,len).
你拷贝的MP3文件应该是要大于定义的数组buf的大小1k的,所以取到最后应该取到最后一次,实际返回的长度小于或者等于1024个字节,这时如果使用read(buf,0,len)会返回恰好的长度,而你使用read(buf),返回的长度肯定是1024,如果你拷贝的文件不是正好是1024的整数倍就肯定会多返回一些字节值的。我用这两种方式都运行了一遍。在文件属性值查得的结果如下:

原文件大小:


read(buf)方式:


read(buf,0,len)方式:


如果你说你所运行的两个方式的程序结果都是一样的,那恭喜你,你的那个MP3文件就正好是1024字节的整数倍了,真神奇~~~

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
王莹 发表于 2012-6-26 19:41
调用的read方法,有两种形式,一种是read(byte [] b),一种是read(byte[] b,int off,int len),对应到你的程 ...

真的,我换一个文件试了试,果然,像你说的一样会比原文件大一点点!
回复 使用道具 举报
王涛 黑马帝 2012-6-27 02:09:41
7#
其实用这个fos.write(buffer, 0,len);主要还是因为你的这个byte[]buffer = new byte[1024];
开辟的这个byte数组的大小事1024,但是实际上很多文件的最后需要装入一个字节数组的字节不会那么正好是1024,也就是说存在了空白的空间,再将这个数组写入时也罢这些无用的空间写入了
这样的操作坑定不合理的,所以定义了一个len变量,记录(len= fis.read(buffer),她的返回值表明了向数组中写入了多少个数据
这样就没有多余的空间呗写入了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马