前言最近在优化我的把PDF转换成word的开源小工具,有时候会遇到一个问题,就是如果我的PDF文件很大,几百兆,如何读得更快更省内存?于是我分析比较了四种常见的文件读取方式,并使用ja
最近在优化我的把PDF转换成word的开源小工具,有时候会遇到一个问题,就是如果我的PDF文件很大,几百兆,如何读得更快更省内存?于是我分析比较了四种常见的文件读取方式,并使用javaVisualVM工具进行了分析。最后的结论是commons-io时间和空都更高效。分析仍然是来自哪个外国巨头。
下面我将给出几种常见的读取大文件的方法。
读取大文件的四种方法首先我在本地压缩了一个文件夹,大概500M。不是很大,但是相对还可以。
方法一:番石榴读作String path = "G:\java书籍及工具.zip";Files.readLines(new File(path), Charsets.UTF_8);
用番石榴读比较简单,一行代码就搞定了。
到下面jdk的bin目录下找到javaVisualVM工具,双击运行即可。
从上图可以看出:
耗时:20秒
堆内存:高达2.5G
CPU消耗:高达50%
我们500M的文件最大堆内存2.5G,如果读取一个2G的文件,我们的电脑可能会直接死机。
模式2: Apache Commons IO正常模式String path = "G:\java书籍及工具.zip";FileUtils.readLines(new File(path), Charsets.UTF_8);
这个方法也比较简单,也是单行代码。跑,也分析一波:
从上图可以看出:
耗时:17秒
堆内存:高达2.5G
CPU消耗:高达50%,流畅运行25%左右。
这个方法和上面的基本一样,肯定不是我想要的。
模式3: Java文件流FileInputStream inputStream = null;Scanner sc = null;try { inputStream = new FileInputStream(path); sc = new Scanner(inputStream, "UTF-8"); while (sc.hasNextLine()) { String line = sc.nextLine(); //System.out.println(line); } if (sc.ioException() != null) { throw sc.ioException(); }} finally { if (inputStream != null) { inputStream.close(); } if (sc != null) { sc.close(); }}
这种方式其实是java中最常见的方式,然后我们运行一个分析波:
从上图可以看出:
耗时:32秒,翻倍。
堆内存:高达1G,减少一半。
CPU消耗:大约25%运行流畅。
这个方法确实很优秀,但是比较费时间。
模式4: Apache Commons IO流LineIterator it = FileUtils.lineIterator(new File(path), "UTF-8");try { while (it.hasNext()) { String line = it.nextLine(); }} finally { LineIterator.closeQuietly(it);}
这样代码看起来很简单,所以只需运行一个wave:
从上图可以看出:
耗时:至少16秒
堆内存:高达650M,减少一半。
CPU消耗:大约25%运行流畅。
好了,就这样吧,牛。
结论通过上面的分析,我们可以得出一个结论,如果要读取一个大文件,选择了错误的方式,可能会极大的占用我的内存和CPU。当文件非常大时,会导致意想不到的问题。
所以为了解决这个问题,有四种常见的读取大文件的方法。通过分析比较,发现Apache Commons IO流是最有效的方式。