java - 下载没有缓冲区的文件: Nio is faster than io?

标签 java io nio

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

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

这个运行完美!但我的 friend 对我说: “嘿,我们有来自 jdk7 的 FileChannel”。 然后我考虑了一下,但我们无法在没有 ByteBuffer 的情况下创建数据并将其导入到 FileChannel 中。

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());

它有效!

最佳答案

Download a file without buffer: Nio is faster than io?

无论您使用经典 I/O 流还是 NIO API,下载时间不太可能有任何差异。

下载速度通常受到网络的限制。诸如此类:

  • 最慢链路的原始数据速率,
  • 端到端网络延迟,
  • 整个路由的拥塞程度(影响数据包被丢弃的可能性),
  • 不存在其他因素(例如路由不稳定、链接/硬件不可靠、“整形”)。

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

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

<小时/>

在您(IMO)在此浪费更多时间之前,我建议您“以简单的方式”实现下载代码。然后对其进行基准测试/分析(通过实际下载)以确定性能瓶颈是否在代码中或(正如我怀疑的那样)在“网络”中。仅当您的测量表明优化代码可能值得时,才去努力优化代码。

<小时/>

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

使用缓冲流与无缓冲流(对于小型 I/O 操作)之间的性能差异比经典流与 NIO 之间的差异要显着几个数量级

关于java - 下载没有缓冲区的文件: Nio is faster than io?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25224604/

相关文章:

java - Stream.sorted().limit() 的性能

java - 为什么在 Java 8 split 中有时会删除结果数组开头的空字符串?

Java登录错误

Java LDAP 搜索似乎无法处理空格

java - 用于搜索和替换大文件中文本的正则表达式

java - 为什么我不能从 FileWriter 获取 FileChannel?

c# - 在后台写入文件

具有 IO 效果的 Haskell 流

java - C++中的内存映射文件用Java读取

Java 将包含文件和结构的子目录移动到父目录