2014-08-30 54 views
0

我有一個大的文件(〜10GB)與可變長度的行,我想以編程方式去不同的行號。有沒有一種有效的方式來做到這一點?Fseek到一個行號(具有可變長度的行)

+2

爲什麼你問,具體用例是什麼? – 2014-08-30 07:31:27

+1

什麼是這個非常大的文件? – 2014-08-30 07:41:21

+0

請編輯你的問題,以解釋你是如何得到如此大的文件。這個從哪裏來? – 2014-08-30 08:08:13

回答

2

沒有有效的方法來做到這一點。線標記結束時,您需要掃描整個文件一次以記憶。

務實地,你需要一個大的循環, getline(3)

你可以記住例如每隔100行的偏移量,可能在大數組或某個索引文件中使用GDBM或某個Sqlite數據庫。

我的感覺是,你根本不應該有這樣一個巨大的文本文件(有一個巨大的文本文件隨機訪問是錯誤的症狀)。如果您需要隨機訪問它,這不是一種有效的方式來存儲這些數據。你可以例如簡化它來填充一些數據庫,等等......可能你不應該把這麼大的數據放在一個文本文件中,而是直接放在數據庫或其他東西里。

1

不直接與fseek,因爲它只能移動一個字節的位置。

如果效率要求來自您必須來回多次執行此操作的簡單解決方案,可以掃描整個文件一次並計算所有行的長度,將它們存儲在映射或數組中,然後使用這些值恰好在您想要的位置移動。

4

是:建立索引。舉例來說,只有一次,你可以創建包含字節各行號的偏移就在旁邊的文本文件,如:

line,offset 
0,0 
10000,48272 
20000,93726 

等,然後,當你想去行13043,就直接跳到抵消48272並跳過另外3043個換行符。簡單而高效。

另一種方法是讓你的線長度保持不變。如果它們已經具有相似的長度,這樣就可以很好地工作,所以不會浪費太多空間。你可以用\0字符或空格或其他任何東西填充它們,然後將文件索引爲一個大矩陣(第N行是N * LEN字節)。

最後,您可以簡單地在行自身的開頭寫上行號。然後在文件中進行二進制搜索,跳到一個換行符,然後檢查下一個行號,以確定是向後還是向前查看(甚至可以猜測多少)。

+2

我會使用'gdbm'或* sqlite * – 2014-08-30 07:32:40

+3

來創建索引文件如果索引使用固定寬度格式,可能會更好,因此您可以跳轉到索引文件中的正確條目以查找文本文件中的位置。 – 2014-08-30 07:32:58

+1

@JonathanLeffler:也許,那麼理論上你會得到O(1)......實際上它可能並不重要,因爲在使用它之前(或許)你會將索引文件加載到內存中。仍然爲你+1。 – 2014-08-30 07:34:38

相關問題