2010-04-03 14 views
0

基本上我需要一個文本文件,如:在Java中,howd我通過線路在文本文件迭代從後到前

弗雷德
伯尼
亨利

和能夠從文件中讀取它們的順序爲

Henry
伯尼
弗雷德

我從閱讀的實際文件是> 30MB,這將是一個不完美的解決方案,以讀取整個文件,將它分成數組,扭轉數組,然後從去那裏。它需要太長時間。我的具體目標是找到第一次出現的字符串(在這種情況下,它是「InitGame」),然後返回該行開頭的位置。

我在python中做過類似的事情。我的方法是尋找文件的末尾 - 1024,然後讀取行,直到完成,然後從我以前的起始點開始尋找另一個1024,然後使用tell(),當我到達先前的位置時停止初始點。所以我會從文件尾部向後讀取這些塊,直到找到我正在尋找的文本。

到目前爲止,我有一段時間在Java中做這件事。任何幫助將不勝感激,如果你住在巴爾的摩附近,甚至可能會得到一些新鮮烘烤的餅乾。

謝謝!

更多信息:

我需要,因爲我讀的文件是一個遊戲,我的主機服務器的日誌文件向後搜索(它是| ERR |城市反恐服務器檢查出來)。日誌文件記錄遊戲中發生的每一個事件,然後我的程序將解析每個事件,處理它並對其進行處理(例如,它跟蹤人們的爆頭,並且會自動踢人的人) )。我需要重新搜索最近的InitGame條目,以便我可以實例化所有玩家對象,並處理自遊戲開始以來需要照顧的任何其他事物。文件中有數百個InitGame事件,但我想要最後一個。如果有更好的方法來做到這一點,不需要向後搜索,請讓我知道。

感謝

+0

餅乾很誘人,但我不在巴爾的摩附近,所以沒有答案給你! ;)實際上,你還沒有明確說明你爲什麼要在文件中向後搜索。如果你不知道目標字符串總是接近尾聲,那麼相對於通過文件前向讀取來說,你正在經歷許多額外的工作。 Java中的seek/tell方法在算法上是相同的,你只需要一個能夠搜索的InputStream。 – msw 2010-04-03 16:05:48

回答

1

可以使用RandomAccessFile的只是重複你的Python的解決方案,並且可以LineNumberReader(或只是閱讀器)的在它上面的自定義子類。

0

Linux有一些很棒的文本解析工具,它可能比嘗試在Java中執行它更合適。

+0

我知道...不幸的是,這個應用程序將在Linux,Windows和Mac上運行。 – rogue780 2010-04-03 18:31:43

0

在向後搜索時,想到了兩個答案。首先是向前搜索,並在到達文件末尾時保留最後找到的InitGame文本(並在您讀取文件時另一個InitGame出現時覆蓋它)。

第二個解決方案是找出文件大小(使用f。長度()),將它分成大塊,它們重疊的次數大於InitGame片段的最大大小(以避免由於在有趣的部分上分割兩個塊而導致的問題),並開始從最後一個塊讀取並朝文件前進開始(使用Reader的skip()函數跳轉到您想要的讀取位置:不需要實際的文件分割)。如果您確定沒有有趣的多字節字符,那麼RandomAccessFile會很有用。

當然,最有效的解決方案是讀取日誌文件輸出,並保留對最後找到的InitGame的引用。這樣你就不必重複讀兩次相同的數據。你甚至可以設置一些東西,這樣你的java程序每隔幾秒鐘就會喚醒一次,查看文件並讀入新添加的行。

0

所以,我需要更詳細的TIL,當我解釋我到底在做什麼。基本上我正在編寫一個管理我運行的遊戲服務器的程序。爲了使程序與遊戲同步,它需要找到最近的InitGame行,然後從那裏讀取,以便它可以記錄所有這些命中,殺死,連接和斷開它從輪的開始所需要的。由於日誌文件可能相當大(我最後一次忘記清理文件超過了500MB),而不是從前面搜索,我想從後面搜索。在Java中,沒有內置的方法來做到這一點。在搜索了大量的互聯網之後,我找到了這個:http://mattfleming.com/node/11。從那裏我拿出BackwardsFileInputStream類並使用它。然後在我的申請中,我扭轉了字符。下一次,我應該能夠構建自己的方法,現在我看到它是如何完成並有更好的理解。

因此,一旦程序從最近的InitGame中讀取日誌文件,它就會模仿tail -f並在寫入日誌文件時讀取它。