这篇文章主要讲解了“怎么用Java高效读取大文件”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用Java高效读取大文件”吧!内存读取第一个版本,阿粉采用内存读取的方式,所有的数据首先读读取到内存中,程序代码如下:logMemory方法如下:上述程序中,阿粉使用 Apache Common-Io 开源第三方库,FileUtils#readLines将会把文件中所有内容,全部读取到内存中。这个程序简单测试并没有什么问题,但是等拿到真正的数据文件,运行程序,很快程序发生了 OOM。之所以会发生 OOM,主要原因是因为这个数据文件太大。假设上面测试文件 test.txt总共有 200W 行数据,文件大小为:740MB。通过上述程序读取到内存之后,在我的电脑上内存占用情况如下:可以看到一个实际大小为 700 多 M 的文件,读到内存中占用内存量为 1.5G 之多。而我之前的程序,虚拟机设置内存大小只有 1G,所以程序发生了 OOM。当然这里最简单的办法就是加内存呗,将虚拟机内存设置到 2G,甚至更多。不过机器内存始终有限,如果文件更大,还是没有办法全部都加载到内存。不过仔细一想真的需要将全部数据一次性加载到内存中?很显然,不需要!在上述的场景中,我们将数据到加载内存中,最后不还是一条条处理数据。所以下面我们将读取方式修改成逐行读取。逐行读取逐行读取的方式比较多,这里阿粉主要介绍两种方式:BufferReaderApache Commons IOJava8 streamBufferReader我们可以使用 BufferReader#readLine 逐行读取数据。Apache Commons IOCommon-IO中有一个方法 FileUtils#lineIterator可以实现逐行读取方式,使用代码如下:这个方法返回一个迭代器,每次我们都可以获取的一行数据。其实我们查看代码,其实可以发现 FileUtils#lineIterator,其实用的就是 BufferReader,感兴趣的同学可以自己查看一下源码。由于公号内无法插入外链,关注『Java极客技术』,回复『20200610』 获取源码Java8 streamJava8 Files 类新增了一个 lines,可以返回 Stream我们可以逐行处理数据。使用这个方法有个好处在于,我们可以方便使用 Stream 链式操作,做一些过滤操作。注意:这里我们使用 try-with-resources 方式,可以安全的确保读取结束,流可以被安全的关闭。并发读取逐行的读取的方式,解决我们 OOM 的问题。不过如果数据很多,我们这样一行行处理,需要花费很多时间。上述的方式,只有一个线程在处理数据,那其实我们可以多来几个线程,增加并行度。下面在上面的基础上,阿粉就抛砖引玉,介绍下阿粉自己比较常用两种并行处理方式。逐行批次打包第一种方式,先逐行读取数据,加载到内存中,等到积累一定数据之后,然后再交给线程池异步处理免费云主机、域名。上述方法,等到内存的数据到达 10000 的时候,拆封两个任务交给异步线程执行,每个任务分别处理 50000 行数据。后续使用 future#get(),等待异步线程执行完成之后,主线程才能继续读取数据。之所以这么做,主要原因是因为,线程池的任务过多,再次导致 OOM 的问题。大文件拆分成小文件第二种方式,首先我们将一个大文件拆分成几个小文件,然后使用多个异步线程分别逐行处理数据。上述方法,首先将一个大文件拆分成多个保存 10W 行的数据的小文件,然后再将小文件交给线程池异步处理。由于这里的异步线程每次都是逐行从小文件的读取数据,所以这种方式不用像上面方法一样担心 OOM 的问题。另外,上述我们使用 Java 代码,将大文件拆分成小文件。这里阿粉还有一个简单的办法,我们可以直接使用下述命令,直接将大文件拆分成小文件:后续 Java 代码只需要直接读取小文件即可。总结当我们从文件读取数据时,如果文件不是很大,我们可以考虑一次性读取到内存中,然后快速处理。如果文件过大,我们就没办法一次性加载到内存中,所以我们需要考虑逐行读取,然后处理数据。但是单线程处理数据毕竟有限,所以我们考虑使用多线程,加快处理数据。感谢各位的阅读,以上就是“怎么用Java高效读取大文件”的内容了,经过本文的学习后,相信大家对怎么用Java高效读取大文件这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是云技术,小编将为大家推送更多相关知识点的文章,欢迎关注!
这篇文章主要介绍“vue转发200状态码如何解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue转发200状态码如何解决”文章能帮助大家解决问题。 首先,需要明确的是,当Vue向后端发送请求时,服务器会返回一个HT…