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要快很多。