2011-06-17 114 views
1

我使用包裝在LineNumberReader中的FileReader來索引大文本文件以便稍後快速訪問。麻煩是我似乎無法找到直接讀取特定行號的方法。 BufferedReader支持skip()函數,但我需要將行號轉換爲一個字節偏移量(或首先索引字節偏移量)。如何將文件的行號轉換爲字節偏移量(或者使用BufferedReader獲取每行開頭的字節偏移量)?

我使用RandomAccessFile對它進行了一次破解,並且在它的工作過程中,它在初始索引過程中非常緩慢。 BufferedReader的速度是太棒了,但是......好吧,你看到了問題。

一些關鍵信息:

  • 文件可以是
  • 它存儲在Android上的內部文件系統的任何大小(目前爲35000線)(通過getFilesDir()是精確的)
  • 的格式是不是固定寬度,不幸的是(因此需要按行讀取)

任何我DEAS?

+1

如果線路沒有固定長度,也沒有直接的方法從行號以字節位置獲得不跟蹤你正在閱讀。當然,除非您在閱讀時創建索引,否則會跟蹤字節位置和行號(正在跟蹤,正如我所提到的)之間的關係。 – 2011-06-17 02:50:26

+0

在初始索引過程中跟蹤字節位置時我完全沒問題,但我該怎麼做?我無法找到一種方法來獲取每個readline()後的當前偏移量,而不使用RandomAccessFile。 – wirbly 2011-06-17 03:05:54

+0

@wirbly使用RandomAccessFile * once *來索引文件,然後在文件中打開一個索引文件和'writeInt(pos)'每個偏移量。 – ironchefpython 2011-06-17 03:22:35

回答

2
+0

link +1;我認爲我在一年前閱讀了鏈接文章,但是懶得再次搜索它:) – Atreys 2011-06-17 17:24:16

+0

我只是簡單地看了一下,看起來可能會做出一些EOL假設,所以人們應該小心。 – MJB 2011-06-17 17:30:57

+0

這絕對是我尋找的夢想班。 :)雖然你對EOL問題是正確的,但我在文件結尾處得到一個IOException。你能看到任何快速修復? (我使用getNextLine()btw) – wirbly 2011-06-17 19:43:02

0

麻煩的是我似乎無法找到一個方法來讀取特定的行號直接

除非你知道每行的長度不能直接讀取它

有沒有捷徑,你需要先讀完整個文件並計算偏移量。

我只是使用BufferedReader,然後獲取每個字符串的長度併爲EOL字符串添加1(或2?)。

+0

文件編碼是否會影響使用string.length()來獲取字節數?如果有,是否有更可靠的方法來獲取每條readline()的實際字節數? – wirbly 2011-06-17 03:11:49

+0

@wirbly是的,編碼將*絕對*對以字節爲單位的行長度產生影響 – ironchefpython 2011-06-17 03:26:08

0

考慮將文件索引與大文本文件一起保存。如果這個文件是你正在生成的東西,無論是在你的服務器還是在設備上,只需要一次生成一個索引並將其與文件一起分發和/或保存,這應該是微不足道的。

我推薦一個int [],其中每個值是第n *(index + 1)行的絕對偏移量(以字節爲單位)。所以你可以有一個大小爲35,000的數組,每行的開始,或者一個大小爲350的數組,每100行開始一行。

這裏假設你有一個index文件,其中包含int類型的原始序列的例子:

public String getLineByNumber(RandomAccessFile index, 
           RandomAccessFile data, 
           int lineNum) { 
    index.seek(lineNum*4); 
    data.seek(index.readInt()); 
    return data.readLine(); 
} 
+0

我會,但我沒有控制原始文本文件的生成,我試圖做的是事後索引生成。原始文件不是靜態的,所以索引必須在運行時創建) – wirbly 2011-06-17 16:56:30

0

剛剛結束了先前的評論:

無論您使用RandomAccessFile先計數字節和第二解析您是通過手動查找線段還是使用LineNumberReader首先逐行讀取行並手動計算每行字符的字節(utf 16中的2個字節)。

0

我把使用 的RandomAccessFile它的裂縫,而它的工作, 那就是你已經開始在硬盤部分 初始索引

時異常緩慢。現在是更難的部分。

BufferedReader中的速度是太棒了, 但是......

有東西在你使用的RandomAccessFile的,使得它比它慢必須是?你一次讀了多少個字節?如果你每次讀一個字節,它將會變得很慢。如果你一次讀入一個字節數組,你可以加速並使用字節數組作爲緩衝區。

+0

我正在使用RandomAccessFile的readline()方法來讀取每一行,並一路跟蹤getFilePointer()的偏移量。更快,然後readline()? – wirbly 2011-06-17 16:53:16

+0

@wirlby,是的。 [readline](http://download.oracle.com/javase/6/docs/api/java/io/RandomAccessFile.html#readLine%28%29),根據其文檔,一次讀取一個字節,直到行終止符被檢測到。MJB的答案正是你想要的:RAF增加了一個緩衝區。 – Atreys 2011-06-17 17:19:08

+0

啊,這就解釋了速度。我正在努力實施MJB的方法。 – wirbly 2011-06-17 19:28:44

相關問題