Files.newInputStream创建慢的InputStream

时间:2013-11-30 06:37:33

标签: java

在我的Windows 7 Files.newInputStream上返回sun.nio.ch.ChannelInputStream。当我测试其性能与FileInputStream时,我惊讶地发现FileInputStream更快。

此测试

    InputStream in = new FileInputStream("test");
    long t0 = System.currentTimeMillis();
    byte[] a = new byte[16 * 1024];
    for (int n; (n = in.read(a)) != -1;) {
    }
    System.out.println(System.currentTimeMillis() - t0);

在125毫秒内读取100mb文件。如果我用

替换第一行
InputStream in = Files.newInputStream(Paths.get("test"));

我得到320毫秒。

如果Files.newInputStream比FileInputStream有什么优势?

4 个答案:

答案 0 :(得分:8)

如果您测试new FileInputStream秒,您可能只是看到了操作系统缓存启动的影响。 Java对I / O绑定进程造成任何重大差异是不可信的。反过来尝试它,并在更大的数据集上。

答案 1 :(得分:2)

我不想成为buzzkill,但是javadoc并没有说明任何优势,也没有任何我能找到的文档

  

打开文件,返回输入流以从文件中读取。的的   流不会被缓冲,并且不需要支持该标记   或重置方法。 该流可安全访问多个   并发线程。阅读从文件开头开始。   返回的流是否可异步关闭和/或   可中断是高度文件系统提供程序特定的因此   未标明。

我认为该方法只是一种实用方法,不一定意味着替换或改进FileInputStream。请注意,并发点可能会解释一些减速。

答案 2 :(得分:0)

每次创建FileInputStream或FileOutputStream时,都在创建一个对象。即使正确并迅速地将其关闭,它也将被放入一个特殊的类别,该类别只有在垃圾收集器执行完整的GC时才会被清除。遗憾的是,由于向后兼容的限制,无法在JDK中立即解决此问题,因为那里可能存在某些代码,其中有人扩展了FileInputStream / FileOutputStream并依靠这些finalize()方法来确保对close()。

https://dzone.com/articles/fileinputstream-fileoutputstream-considered-harmful

答案 3 :(得分:-2)

该文件说

“流不会被缓冲”

这是因为Files.newInputStream(Paths)支持非阻塞IO。

你可以尝试在调试模式下,你可以打开非阻塞输入流并同时修改文件,但是如果你使用FileInputStream,则不能做这样的事情。

FileInputStream将需要“写入锁定”文件,因此它可以缓冲文件内容,提高读取速度。

但是ChannelInputStream不能。它必须保证它正在读取文件的“当前”内容。

以上是我的经验,我没有检查Java doc中的每一点。