[英]How to read a large file using Nio2
我正在嘗試讀取一個文本文件,截至目前,該文件大約有30萬行。
我怎么讀書?
我正在使用java.io.BufferedReader閱讀
這是一個代表我的方法的小代碼段。
int lineNumber = 1;
BufferedReader br = null;
String currentLine = null;
br = new BufferedReader(new FileReader(f));//here f will be the file name to be read, I have passed
while ((cuurentLine = br.readLine()) != null) {
//here I have written logic to do processing after reading 1000 lines
//line number = 1001 start processing, similarly it reads next 1000 lines, each line is put in a List collection
//after reaching 1001 line clearing list and continuing the loop
}
我在以下情況下嘗試使用NIO2
br = Files.newBufferedReader(Paths.get(inputFileName), StandardCharsets.UTF_16);
這導致了以下異常
exception :Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuffer.append(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at TexttoExcelMerger.readFileLineByLine(TexttoExcelMerger.java:66)
at TexttoExcelMerger.main(TexttoExcelMerger.java:255)
首先,我的方法正確嗎?
NIO2,apache FileUtils或任何其他API中是否有任何有效且快速的方法來更快地讀取文件,從而更快地改善了我的文件讀取過程。 我可以像前1000條一樣閱讀行集嗎
br.readFirst(1000);
,
但沒有像我的邏輯那樣逐行閱讀或迭代?
任何將整個文件讀入內存的方法都注定會失敗。 遲早該文件將超出可用內存,並且該程序將停止運行,必須完全重新設計。 這不是一個好的故障模式,因為在此期間用戶無能為力。 您當時正在割草。 您甚至想對帶有數十萬行的文件進行嘗試。 一次重新考慮和處理一條線。 或使用數據庫。
注意:不要騙自己。 您正在使用java.io讀取文件。 這里的NIO2組件很小。 完全不是您需要它。
您內存不足,因為您試圖將太多文件讀入內存。 我可以想到這有兩種方式。
你是故意的
如果您要保存讀入的每一行,將耗盡內存。
while ((curentLine = br.readLine()) != null) {
stringBuilder.append(currentLine);
}
如果您只想一次保存1000行,則可以使用-Xmx
來增加Java的堆大小並可以。 這完全取決於1000行占用的內存量。
你不小心在做
如果您正在讀取的文件沒有換行符,則br.readLine()
會嘗試讀取整個內容,並認為這是一條巨大的長行。
如果您想象一個任意的文本文件,那只是一長串字符。 其中一些字符( EOL
)對人類和許多程序都有特殊的意義,但它們仍然只是字符。 這意味着您不能不閱讀前面的每個字符就說“給我第十行文本”(因為您永遠不知道哪個字符可能是您需要計算的EOL
)。
您可以使用固定長度的記錄格式:您說每行將完全是$ n $個字符(例如80個字符)。 現在,如果要跳到第10行,則可以跳到第800個字符。 但是,如果您實際上使用的是UTF-16,則字符不是char
,這實際上是行不通的。
可以,因為此時您可能應該使用數據庫。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.