FileInputStream和Files.newInputStream?
前言
在上传文件的时候,发现还有一个新的东西叫做Files.newInputStream
,就稍微看了一下下。主要应用示例在这篇文章中。
FileInputStream
很久很久以前就开始用这个库了,是一个文件流,可以读取文件。
主要用法也是直接新建:
1 | FileInputStream fis = new FileInputStream("filePath"); |
或者
1 | FileInputStream fis = new FileInputStream(new File("filePath")); |
在源码中这两个的效果也是一样的。
使用完毕后,关闭:
1 | fis.close(); |
或者你想稳妥一点:
1 | fis.finalize(); |
这个库主要就是以只读的方式打开文件,读取文件,最后处理。就不再多说了。网上研究这个的人比我吃的饭都多。
Files.newInputStream
这个库是java.nio.file.Files
中的方法,是FileInputStream
的升级版。
我们来看看这个玩意的源码是什么意思:
1 | public static InputStream newInputStream(Path path, OpenOption... options) throws IOException { |
通过自己的静态方法provider
,获取到FileSystemProvider
,然后调用newInputStream
方法。
这个FileSystemProvider
是一个抽象类,也提供了一个newInputStream
方法:
1 | public InputStream newInputStream(Path path, OpenOption... options) throws IOException { |
在这里,将通过Channels
类的newInputStream
方法给出输入流。
为什么偏偏要这么做呢?
最后看到这个方法是这样的:
1 | /** |
不难看出,这个方法的优势正如注释所述,是线程安全的。
为什么偏偏他是线程安全的?
这就是sun.nio.ch
的ChannelInputStream
类的作用了。这个类以ReadableByteChannel
作为构造函数。ReadableByteChannel
类是这样注释的:
1 | /** |
这就是线程安全的非阻塞IO
的核心了。
所以,不难看出,这个类最核心的地方就是将IO
模式转变为非阻塞的NIO
模式,这也顺应了现阶段高吞吐量或处理大文件的应用场景,趁着CPU
把任务丢给磁盘的时候,趁着闲下来的时间做点别的事,提升处理效率。
而这一点,也使得Files.newInputStream
能够进一步与其他的NIO
操作集成,从而在处理大文件的时候,充分利用缓冲区的优势,处理起来也比FileInputStream
要快很多。