下载没有缓冲区的文件:Nio比io快?

时间:2014-08-10 01:09:12

标签: java io nio

我正在为我的项目开发更新程序,我想快速下载文件。 每次更新时,都有一些文件大小不同。所以我认为我不需要缓冲区,或者肯定没有定义。我写的那样:

File file = new File..
InputStream input = new InputStream...
OutputStream output = new OutputStream(..).write(input.read());

这一个完美运行!但是我的朋友对我说; “嘿,我们从jdk7获得了FileChannel”。 我已经考虑过了,但是我们无法创造和将数据导入FileChannel而不使用ByteBuffer。

FileChannel channel = new FileOutputStream(file).getChannel();

ByteBuffer buffer = ByteBuffer.allocateDirect(..);
buffer.putInt(inputstream.read());

channel.write(buffer);

那么什么更快?好吗?谢谢!

更新:(我认为,最快的解决方案)

URLConnection connection = new URL(url).openConnection();

File file = new File(connection.getURL().getPath().substring(1));
if (file.getParentFile() != null)
    file.getParentFile().mkdirs();

FileChannel output = new FileOutputStream(file).getChannel();
output.transferFrom(Channels.newChannel(connection.getInputStream()), 0, connection.getContentLengthLong());

有效!

1 个答案:

答案 0 :(得分:4)

  

下载没有缓冲区的文件:Nio比io快?

无论使用传统的I / O流还是NIO API,不太可能对下载时间产生任何影响。

下载速度通常受网络限制。比如:

  • 最慢链接的原始数据速率
  • 端到端网络延迟,
  • 整个路由的拥塞量(这会影响数据包被丢弃的可能性),
  • 没有其他因素(例如路线不稳定,链接/硬件不可靠,“塑造”)。

然后,存在“另一端”是否能够以“网络”能够承载的速率提供(或消费)数据的问题。这通常取决于光盘和网络I / O带宽以及另一端的负载。

一般来说,客户端将数据从内存缓冲区移动到本地目标文件的能力不是问题。


在您(IMO)浪费更多时间之前,我建议您实施下载代码“简单方法”。然后对其进行基准测试/配置(使用实际下载)以确定性能瓶颈是在代码中还是(我怀疑)在“网络”中。只有在您的测量表明它可能值得的时候才能优化您的代码。


更新 - 我刚刚注意到在您的原始版本中,您一次读取一个字节数据(使用来自无缓冲输入流的read()。这个绝对是效率低下,可能会对下载速度造成影响。如果要以小块(例如一次一个字节)从流中读取(或写入流),那么应该将其包装起来使用相应的缓冲流;例如BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter

使用缓冲流与非缓冲流之间的性能差异(对于小型I / O操作)数量级比经典流与NIO之间的差异更重要。