【问题标题】:Download big file is too slow下载大文件太慢
【发布时间】:2015-12-07 09:44:32
【问题描述】:

我遇到了这样的场景。

我的项目收到来自 perl 的下载请求

void downloadRequest(FileItemIterator items,
                             HttpServletResponse response) throws Exception
{ 
log.info("Start downloadRequest.......");
OutputStream os = response.getOutputStream();
File file = new File("D:\\clip.mp4");
            FileInputStream fileIn = new FileInputStream(file);
            //while ((datablock = dataOutputStreamServiceImpl.readBlock()) != null)
            byte[] outputByte = new byte[ONE_MEGABYE];
            while (fileIn.read(outputByte) != -1)
            {

                System.out.println("--------" + (i = i + 1) + "--------");
                System.out.println(new Date());
                //dataContent = datablock.getContent();
                System.out.println("Start write " + new Date());
                os.write(outputByte);
                System.out.println("End write " + new Date());
                //System.out.println("----------------------");
            }
            os.close();
        }
    }

我尝试从文件中读取和写入 1MB 的块。但是,下载整个文件需要很长时间。 (对于 100MB 的文件,我的情况是 20 分钟)

我尝试 sysout,我看到了这样的结果:

前几个块可以非常快地读取、写入数据:

--------1--------
Mon Dec 07 16:24:20 ICT 2015
Start write Mon Dec 07 16:24:20 ICT 2015
End write Mon Dec 07 16:24:21 ICT 2015
--------2--------
Mon Dec 07 16:24:21 ICT 2015
Start write Mon Dec 07 16:24:21 ICT 2015
End write Mon Dec 07 16:24:21 ICT 2015
--------3--------
Mon Dec 07 16:24:21 ICT 2015
Start write Mon Dec 07 16:24:21 ICT 2015
End write Mon Dec 07 16:24:21 ICT 2015

但是下一个块比上一个慢

--------72--------
Mon Dec 07 16:29:22 ICT 2015
Start write Mon Dec 07 16:29:22 ICT 2015
End write Mon Dec 07 16:29:29 ICT 2015
--------73--------
Mon Dec 07 16:29:29 ICT 2015
Start write Mon Dec 07 16:29:29 ICT 2015
End write Mon Dec 07 16:29:37 ICT 2015

--------124--------
Mon Dec 07 16:38:22 ICT 2015
Start write Mon Dec 07 16:38:22 ICT 2015
End write Mon Dec 07 16:38:35 ICT 2015
--------125--------
Mon Dec 07 16:38:35 ICT 2015
Start write Mon Dec 07 16:38:35 ICT 2015
End write Mon Dec 07 16:38:48 ICT 2015

我真的不明白 outputStream 是怎么写的,为什么要花这么长时间?还是我犯了一些错误?

对不起,我的英语不好。我真的需要你的支持。提前致谢!

【问题讨论】:

  • 每次写入后刷新流有什么改变吗?
  • 无法保证read(...) 方法将填充outputByte 数组,此外,您应该检查!= -1 而不是!= 1
  • @Berger 我已经尝试刷新每个写入但结果相同
  • 您可能想使用缓冲区大小,尝试较低的值。
  • @Titus:是的,这是我写问题时的错误,但在我的代码中是-1。但是你对表演有任何想法吗?为什么它需要太慢? :(

标签: java perl download outputstream


【解决方案1】:

无法保证read(byte[] b) 方法会从文件中读取b.length 字节数,这意味着您的代码可能发送的字节数可能比文件实际具有的字节数多。

例如,如果您正在处理一个 10 MB 的文件,而 read(byte[] b) 始终从该文件中读取 b.length/2,您将发送 20 MB。

要解决这个问题,您可以这样做。

 byte[] outputByte = new byte[ONE_MEGABYE];
 int r = -1;
 while ((r = fileIn.read(outputByte)) != -1){            
      os.write(outputByte,0,r);            
 }

这将确保您发送的字节数与从文件中读取的字节数一样多。

除了这个问题之外,速度还可能受到许多其他因素的影响,例如互联网速度或其他程序的实施。

【讨论】:

  • 谢谢你的好点,但性能仍然一样。关于网络,现在一切都在我的本地,您还有其他想法吗? :(
  • @MCT 尝试更改缓冲区大小 here you can find more info about that 也,您应该考虑使用缓冲流,如 BufferedInputStreamBufferedOutputStream
猜你喜欢
  • 1970-01-01
  • 2015-11-15
  • 1970-01-01
  • 2021-12-08
  • 2019-06-10
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
相关资源
最近更新 更多