这篇文章主要是讲解展现,在Java中如何高效的读取大文件中的数据。html
通常状况下,咱们都是在内存中读取文件——Guava 和 Apache Commons IO 提供了快速的方法:
java
Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path));<br />这样作的方法有个问题就是,文件会被保存在内存中,若是文件太大的话,会形成OutOfMemoryError 下面举个例子,读取1Gb的文件:
@Test public void givenUsingGuava_whenIteratingAFile_thenWorks() throws IOException { String path = ... Files.readLines(new File(path), Charsets.UTF_8); }刚开始内存使用:
[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory: 128 Mb [main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory: 116 Mb读取全部文件后,咱们再来看看内存使用
[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory: 2666 Mb [main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory: 490 Mb咱们能够看到。大约2.1Gb的内存被消耗。缘由很简单,这个方法将文件彻底加载到了内存当中。 经过以上的验证,咱们能够清楚的知道。将全部的文件都保存在内存中是很是消耗内存的。 还有就是,咱们一般也不须要把文件都放在内存中来读。咱们须要的是对文件的循环读取,须要的功能是读取——处理——丢弃。咱们要作的就是,依次读取依次遍历全部的文件。
如今咱们来看一下解决方法,咱们用到java.util.Scanner 来获取文件内容,而且依次读取数据内容: code
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); } // note that Scanner suppresses exceptions if (sc.ioException() != null) { throw sc.ioException(); } } finally { if (inputStream != null) { inputStream.close(); } if (sc != null) { sc.close(); } }这个方法遍历了文件全部内容,能够处理每一行的记录。没有将内容一直存在内存中:
[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory: 763 Mb [main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory: 339 Mb</p>
这篇文章就讲解了读取一个大文件的一个不错的方法。能够减小一些没必要要的内存使用htm