黑马程序员技术交流社区

标题: 关于字节流copy mp3的一个新问题(已更新) [打印本页]

作者: 张立江    时间: 2012-6-18 08:30
标题: 关于字节流copy mp3的一个新问题(已更新)
本帖最后由 小张童鞋 于 2012-6-19 14:04 编辑

经过唐辉辉童鞋的提示,问题解决了,我忘记将数据写进数组bfu里面了。
但是又出来了一个新的问题,在没将数据写进数组里的时候,为什么新的MP3数据会大过原先的MP3并且一直膨胀呢?

早上起来写了下这个程序,结果程序一直挂在那里不动了,在每次循环里面我加了flush(),注释掉就正常了.
这是为什么?
  1. import java.io.*;

  2. class CopyTest
  3. {
  4.         public static void main(String[] args) throws IOException
  5.         {
  6.                 long start = System.currentTimeMillis();
  7.                 copy();
  8.                 long end = System.currentTimeMillis();
  9.                 System.out.println((end-start)+"毫秒");
  10.         }

  11.         public static void copy()throws IOException
  12.         {
  13.                 BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("G:\\kugou\\醉拳_1.mp3"));
  14.                 BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("g:\\kugou\\醉拳.mp3"));

  15.                 int len = 0;

  16.                 while ((len=bufis.read())!=-1)
  17.                 {
  18.                         bufos.write(len);
  19.                         bufos.flush();
  20.                 }

  21.                 bufos.close();
  22.                 bufis.close();
  23.         }
  24. }
复制代码

作者: 刘笑    时间: 2012-6-18 09:00
flush() 是把缓冲区的数据强行输出.主要用在IO中,即清空缓冲区数据,一般在读写流(stream)的时候,数据是先被读到了内存中,再把数据写到文件中,当你数据读完的时候不代表你的数据已经写完了,因为还有一部分有可能会留在内存这个缓冲区中。这时候如果你调用了close()方法关闭了读写流,那么这部分数据就会丢失,所以应该在关闭读写流之前先flush()。
作者: 张立江    时间: 2012-6-18 09:14
刘笑 发表于 2012-6-18 09:00
flush() 是把缓冲区的数据强行输出.主要用在IO中,即清空缓冲区数据,一般在读写流(stream)的时候,数据是 ...

我是在关闭读写流之前进行了flush()的呀
作者: 唐辉辉    时间: 2012-6-18 09:18
本帖最后由 唐辉辉 于 2012-6-18 09:20 编辑

楼主程序有点问题。
while ((len=bufis.read())!=-1)
{
          bufos.write(len);
          bufos.flush();
}
这里相当每次循环都给一个字节给len然后写入到目标文件中。多少个字节就得循环和刷新缓冲区多少次!这样速度当然非常慢。而不是不动了。
建议定义一个byte型数组用于一次存储一定的数据量,再一次性写入目标文件中。这样速度就很快了。

byte[] buf = new byte[1024];
int len = 0;

while ((len = bufis.read(buf)) != -1) {
      
bufos.write(buf,0,len);
     
bufos.flush();
}
作者: 孙峰    时间: 2012-6-18 09:20
刘笑 发表于 2012-6-18 09:00
flush() 是把缓冲区的数据强行输出.主要用在IO中,即清空缓冲区数据,一般在读写流(stream)的时候,数据是 ...

你也把程序看完了再回答问题
作者: 袁培育    时间: 2012-6-18 09:22
你把flush()打开(即把注释去掉),因为你的read方法一次读一个字节,读一个就flush一次速度肯定很慢,你多等一会,可能得等3到5分钟,不过应该不会超过10分钟,我怀疑是速度太慢导致你误以为程序停掉。从代码上看不出有什么问题,加上flush应该也能运行的。楼主不妨试试,给它10分钟时间,如果楼主不想等那么长时间的话,可以再flush前后加上输出语句,如果程序运行时执行了输出语句那么说明程序没错。
作者: 刘笑    时间: 2012-6-18 09:28
小张童鞋 发表于 2012-6-18 09:14
我是在关闭读写流之前进行了flush()的呀

额,楼主理解错了,最后一句话是论证了为什么要flush,而不是flush和close的先后问题。楼主好好品品
作者: 刘笑    时间: 2012-6-18 09:28
孙峰 发表于 2012-6-18 09:20
你也把程序看完了再回答问题

我最后一句话想强调的是应该用flush,而不是flush和close的顺序问题
作者: 张立江    时间: 2012-6-18 09:30
唐辉辉 发表于 2012-6-18 09:18
楼主程序有点问题。
while ((len=bufis.read())!=-1)
{

试过了,也不行,运行了之后程序没停下来,强制结束程序后我看了下2个MP3文件,发现新建立的MP3文件太大了
作者: 唐辉辉    时间: 2012-6-18 09:34
小张童鞋 发表于 2012-6-18 09:30
试过了,也不行,运行了之后程序没停下来,强制结束程序后我看了下2个MP3文件,发现新建立的MP3文件太大 ...

不可能错!   我这里是正常的,请你仔细检查下代码。
作者: 孙峰    时间: 2012-6-18 09:38
本帖最后由 孙峰 于 2012-6-18 09:44 编辑

楼主在复制字节时既然用到Buffered就最好指定缓冲区啊,没有指定中间缓冲区,应该  byte[]  buf=new byte[1024];,然后 bufis.read(buf), 将数据读取到字节数组中,再 bufos.write(buf,0,len) 将字节数组中数据写出。
作者: 常佳杰    时间: 2012-6-18 09:53
应该写上抛出异常语句试试




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