黑马程序员技术交流社区

标题: IO问题,从未发现! [打印本页]

作者: 。。。。。。。    时间: 2014-1-14 09:35
标题: IO问题,从未发现!
利用字节流缓冲区复制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.         }
复制代码

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

作者: jibenwujie    时间: 2014-1-14 09:43
在你读写的时候,会有一个缓冲区,你每进行一次读写就会刷新一次该缓冲区,
而你在读完的时候,还需要一次刷新,来使得文件完整,
如果你去查看api , close方法是在关闭前刷新该流
希望能解决楼主困惑
作者: 。。。。。。。    时间: 2014-1-14 10:34
jibenwujie 发表于 2014-1-14 09:43
在你读写的时候,会有一个缓冲区,你每进行一次读写就会刷新一次该缓冲区,
而你在读完的时候,还需要一次 ...

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

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

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

字节高效流:

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


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



作者: 黄晓鑫    时间: 2014-1-14 12:57
因为关闭才会刷新如果不关闭 就在流里面 所以不关是有区别的
作者: 李洋-    时间: 2014-1-14 14:03
字节流是不用刷新流的,你这种读取方法是一次读取一个字节,你可以用一次读取一个字节数组试试
作者: 放课后小朋友    时间: 2014-1-16 14:40
明显没有flush刷新操作,关闭流包含刷新操作,既然没有刷新,查看api应该能知道原因,结果也没找到,但肯定的是,少写了一些不太重要的东西,因为文件能播放{:soso_e144:}




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