簡體   English   中英

如何使用Nio2讀取大文件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM