完美解決java讀取大文件內(nèi)存溢出的問(wèn)題
1. 傳統(tǒng)方式:在內(nèi)存中讀取文件內(nèi)容
讀取文件行的標(biāo)準(zhǔn)方式是在內(nèi)存中讀取,Guava 和Apache Commons IO都提供了如下所示快速讀取文件行的方法:
Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path));
實(shí)際上是使用BufferedReader或者其子類(lèi)LineNumberReader來(lái)讀取的。
傳統(tǒng)方式的問(wèn)題: 是文件的所有行都被存放在內(nèi)存中,當(dāng)文件足夠大時(shí)很快就會(huì)導(dǎo)致程序拋出OutOfMemoryError 異常。
問(wèn)題思考:我們通常不需要把文件的所有行一次性地放入內(nèi)存中,相反,我們只需要遍歷文件的每一行,然后做相應(yīng)的處理,處理完之后把它扔掉。所以我們可 以通過(guò)行迭代方式來(lái)讀取,而不是把所有行都放在內(nèi)存中。
2. 大文件讀取處理方式
不重復(fù)讀取與不耗盡內(nèi)存的情況下處理大文件:
(1)文件流方式:使用java.util.Scanner類(lèi)掃描文件的內(nèi)容,一行一行連續(xù)地讀取
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);
}
}catch(IOException e){
logger.error(e);
}finally {
if (inputStream != null) {
inputStream.close();
}
if (sc != null) {
sc.close();
}
}
該方案將會(huì)遍歷文件中的所有行,允許對(duì)每一行進(jìn)行處理,而不保持對(duì)它的引用。總之沒(méi)有把它們存放在內(nèi)存中!
(2)Apache Commons IO流:使用Commons IO庫(kù)實(shí)現(xiàn),利用該庫(kù)提供的自定義LineIterator
LineIterator it = FileUtils.lineIterator(theFile, UTF-8);
try {
while (it.hasNext()) {
String line = it.nextLine();
// do something with line
}
} finally {
LineIterator.closeQuietly(it);
}
該方案由于整個(gè)文件不是全部存放在內(nèi)存中,這也就導(dǎo)致相當(dāng)保守的內(nèi)存消耗。
以上這篇完美解決java讀取大文件內(nèi)存溢出的問(wèn)題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot優(yōu)雅獲取前端參數(shù)的方法詳解
現(xiàn)在的項(xiàng)目基本上都是前后端分離的項(xiàng)目,如何打通前后端,接收前端傳過(guò)來(lái)的參數(shù)呢,這篇文章小編就來(lái)和大家詳細(xì)介紹一下springboot如何優(yōu)雅的獲取前端參數(shù)吧2024-03-03
SpringBoot中FailureAnalyzer的使用詳解
這篇文章主要介紹了SpringBoot中FailureAnalyzer的使用詳解,FailureAnalyzer攔截啟動(dòng)時(shí)異常,將異常轉(zhuǎn)換成更加易讀的信息并包裝成org.springframework.boot.diagnostics.FailureAnalysis對(duì)象,監(jiān)控應(yīng)用啟動(dòng)過(guò)程,需要的朋友可以參考下2023-12-12
spring boot項(xiàng)目中MongoDB的使用方法
前段時(shí)間分享了關(guān)于Spring Boot中使用Redis的文章,除了Redis之后,我們?cè)诨ヂ?lián)網(wǎng)產(chǎn)品中還經(jīng)常會(huì)用到另外一款著名的NoSQL數(shù)據(jù)庫(kù)MongoDB。下面這篇文章主要給大家介紹了關(guān)于在spring boot項(xiàng)目中MongoDB的使用方法,需要的朋友可以參考下。2017-09-09
ElasticSearch如何設(shè)置某個(gè)字段不分詞淺析
最近在學(xué)習(xí)ElasticSearch官方文檔過(guò)程中發(fā)現(xiàn)的某個(gè)問(wèn)題,記錄一下 希望能幫助到后面的朋友,下面這篇文章主要給大家介紹了關(guān)于ElasticSearch如何設(shè)置某個(gè)字段不分詞的相關(guān)資料,需要的朋友可以參考下2022-04-04
MyBatisPlus查詢報(bào)錯(cuò)Unknow?column?‘id‘?in?‘field?list‘解決分析
這篇文章主要為大家介紹了MyBatisPlus查詢報(bào)錯(cuò)Unknow?column?‘id‘?in?‘field?list‘解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
SpringMVC使用注解實(shí)現(xiàn)登錄功能
這篇文章主要為大家詳細(xì)介紹了SpringMVC使用注解實(shí)現(xiàn)登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09

