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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 。。。。。。。 中级黑马   /  2014-1-14 09:35  /  1121 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

利用字节流缓冲区复制Mp3的时候,不关闭资源的话复制后的Mp3文件比实际的小?这是为什么?
  1. public static void main(String[] args)throws Exception {
  2.                 BufferedInputStream bws = new BufferedInputStream (new FileInputStream("J:\\01.mp3"));
  3.                 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\03.mp3"));
  4.                 int i=0;
  5.                 while((i=bws.read())!=-1){
  6.                         bos.write(i);
  7.                 }
  8.                 //bws.close();
  9.                 //bos.close();
  10.         }
复制代码

如果关闭了资源,大小又一致了!
在线坐等答案!

评分

参与人数 1技术分 +1 收起 理由
FFF + 1 神马都是浮云

查看全部评分

6 个回复

倒序浏览
在你读写的时候,会有一个缓冲区,你每进行一次读写就会刷新一次该缓冲区,
而你在读完的时候,还需要一次刷新,来使得文件完整,
如果你去查看api , close方法是在关闭前刷新该流
希望能解决楼主困惑

评分

参与人数 1黑马币 +3 收起 理由
FFF + 3 淡定

查看全部评分

回复 使用道具 举报
jibenwujie 发表于 2014-1-14 09:43
在你读写的时候,会有一个缓冲区,你每进行一次读写就会刷新一次该缓冲区,
而你在读完的时候,还需要一次 ...

谢谢你的回答,但是请注意这是字节流BufferedOutputStream,本身就带有缓冲区,是直接从缓冲区中读写的,还需要刷新吗?
回复 使用道具 举报
本帖最后由 高亮亮 于 2014-1-14 11:02 编辑

因为你在读取的时候,没有加入flush();
这样的情况,有两种:
一种是PrintXxx流中可以,(前提是开启了自动刷新,并使用固定的输出方式)
另一种是普通的字节流,这样的流中的write(int byte)写一个字节是不用刷新的.
而如果用的是缓冲区的字节流,这样的流中writh(int byte)实际上是自动刷到了缓冲区中的一个byte数组中,而这个缓冲区是隔一段固定时间刷新写入文件一次.所以,你最后一次结束的时候,未close(),那一组数据可能未刷新.这样就丢失那最后一组的数据.具体情况,JDK源码应该可以看到些东东.

下面是我的试验:
普通字节流:

字节高效流:

左边为源文件,右边为高效字节流,都没有给刷新语句和结束语句.


结论:
我的分析是没错的.
普通字节流没问题.
用的缓冲字节流的话,要考虑最后那个缓冲区数据让他写入目标文件才行....


评分

参与人数 1技术分 +2 收起 理由
FFF + 2 赞一个!

查看全部评分

回复 使用道具 举报 1 0
因为关闭才会刷新如果不关闭 就在流里面 所以不关是有区别的
回复 使用道具 举报
字节流是不用刷新流的,你这种读取方法是一次读取一个字节,你可以用一次读取一个字节数组试试
回复 使用道具 举报
明显没有flush刷新操作,关闭流包含刷新操作,既然没有刷新,查看api应该能知道原因,结果也没找到,但肯定的是,少写了一些不太重要的东西,因为文件能播放{:soso_e144:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马