我需要從大文件中讀取最後n行(比如2GB)。該文件是UTF-8編碼的。java中的RandomAccessFile是否讀取內存中的整個文件?
想知道最有效的方法。閱讀關於Java中的RandomAccessFile,但執行seek()方法,讀取內存中的整個文件。它使用本機實現,所以我無法引用源代碼。
我需要從大文件中讀取最後n行(比如2GB)。該文件是UTF-8編碼的。java中的RandomAccessFile是否讀取內存中的整個文件?
想知道最有效的方法。閱讀關於Java中的RandomAccessFile,但執行seek()方法,讀取內存中的整個文件。它使用本機實現,所以我無法引用源代碼。
1)RandomAccessFile.seek只是設置文件指針的當前位置,沒有字節被讀入內存。
2)由於你的文件是UTF-8編碼的,它是一個文本文件。爲了閱讀文本文件,我們通常使用BufferedReader,Java 7甚至增加了一個方便的方法File.newBufferedReader來創建一個BufferedReader的實例來從文件中讀取文本。儘管閱讀最後n行可能效率不高,但易於實現。
3)爲了高效率,我們需要RandomAccessFile並從最後開始向後讀文件。下面是一個基本的例子
public static void main(String[] args) throws Exception {
int n = 3;
List<String> lines = new ArrayList<>();
try (RandomAccessFile f = new RandomAccessFile("test", "r")) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
for (long length = f.length(), p = length - 1; p > 0 && lines.size() < n; p--) {
f.seek(p);
int b = f.read();
if (b == 10) {
if (p < length - 1) {
lines.add(0, getLine(bout));
bout.reset();
}
} else if (b != 13) {
bout.write(b);
}
}
}
System.out.println(lines);
}
static String getLine(ByteArrayOutputStream bout) {
byte[] a = bout.toByteArray();
// reverse bytes
for (int i = 0, j = a.length - 1; j > i; i++, j--) {
byte tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
return new String(a);
}
它讀取字節的起始從尾到ByteArrayOutputStream之後的文件字節,當到達LF它反轉字節,並創建一個線。
有兩件事情需要改進:1)緩衝2)EOL識別
你可以包括如何在不讀取整個文件的情況下使用BufferedReader嗎? – 2013-03-25 10:36:34
由於它逐行讀取,因此不會將整個文件讀入內存 – 2013-03-25 10:48:38
我想說,因爲它從一開始就逐行讀取,所以它將整個文件讀入內存,即使它不加載整個文件文件一次。 – 2013-03-25 12:00:22
如果你需要隨機訪問,你需要的RandomAccessFile。如果你知道你在做什麼,你可以將你從這裏得到的字節轉換成UTF-8。
如果您使用BuffredReader,您可以使用跳過(n)的字符數,這意味着它必須讀取整個文件。
一種組合的方式;使用FileInputStream和skip(),通過讀回N個換行符找到要讀取的位置,然後將該流包裝到BufferedReader中以讀取UTF-8編碼的行。
這是否意味着,一天結束,我最終讀取整個文件在記憶中 ? – 2013-03-25 10:40:00
如果您按照我的建議去做,則不行。如果你單獨使用BufferedReader,它會讀取整個文件,這是我不建議你這樣做的。 – 2013-03-25 10:41:21
可以請你分享一下這個新手代碼片段:(我想達到文件結尾,追溯到n行,然後讀取n行到我的內存 – 2013-03-25 10:46:08
不,「seek()」不會將* anything *讀入內存,更不用說整個文件了。你完全可以控制。 – NPE 2013-03-25 10:28:31
我通讀了那個問題,但是我想明白,如果文件如果是UTF-8編碼的話,那麼是否使用RandomAccessFile氣餒? – 2013-03-25 10:31:36
不同意重複。這更多地關注RandomAccessFile,而另一個關於應用程序,甚至沒有提到RAF。 – 2015-03-03 08:46:39