2009-08-27 89 views
2

我遇到了一個問題,試圖解析文件的ascii部分,一旦我打到結束標記,IMMEDIATELY開始讀取該點上的字節。我在Java中所知道的讀取一行或整個單詞的所有內容都會創建一個緩衝區,這會破壞在停止點之後立即獲取字節的任何機會。唯一的方法就是逐字節地讀取數據,找到換行符,在換行之前重建所有內容,查看它是否是我的結束標記,然後從那裏開始?Java - 是否可以逐行讀取文件,停止,然後立即開始讀取停止的字節?

回答

1

這個文件有多大?我的第一個想法是將整個事件讀入ByteBuffer或ByteArrayOutputStream而不嘗試處理它,然後通過比較字節值來定位標記。一旦您知道文本部分結束並開始二進制部分,就會適當地處理每個部分。

+0

不是很大的文件;我喜歡這個簡單。我會試試看。 – sepiroth 2009-08-27 18:43:47

+0

其實我真的很喜歡這個,現在我讀了它。所以這個計劃是將漏洞讀入一個字節緩衝區(我知道文件有多大,以字節爲單位,所以這個緩衝區將是正確的大小)。然後我搜索我的結束標記的字節緩衝區,然後我在那裏切分緩衝區。那會有用嗎?我想想搜索我的結束標籤將涉及搜索第一個字節,如果找到,檢查第二,第三等確認。 – sepiroth 2009-08-27 18:48:30

+0

這就是我的想法。 – 2009-08-27 18:55:56

0

是的,你是正確的逐字節。抽象有其缺點。

+0

@crimson:AAAAAAARRRRRRRRRRRRGGGGGGGGGGGGGG – sepiroth 2009-08-27 14:22:03

+0

Java的性格和字節流之間的強區別,同時確保您始終正確處理數據和字符串和編碼區分它們有用,確實讓這個有點困難。 – 2009-08-27 14:23:02

2

這是可能的,但據我所知不是從API的類。

您可以手動完成 - 將其打開爲BufferedInputStream,它支持mark/reset。您逐塊讀取(byte[]),並將其解析爲ASCII。最終你將它累積在一個緩衝區中,直到你點擊標記。 但在此之前read請致電mark。如果您確信自己讀取了ASCII中所需的所有內容,則可致電reset,然後致電read轉儲剩餘的ASCII部分。現在你有一個BufferedInputStream(這是一個InputStream)準備好讀取文件的二進制部分。

+0

等待,這將如何工作?我不知道結束標記有多遠,所以我能想到的唯一數據結構就是一個數組列表。看着緩衝區,似乎我需要知道分配給它多少,我不知道。是處理這個東西的最佳方式一個數組列表? – sepiroth 2009-08-27 17:10:07

+0

您讀取100個字節。它是否包含結束標記(由於ASCII編碼,易於測試)?不,那是它的一部分。記住它在某處(將其解析爲字符串)。你讀下一個塊。再次,它不包含結束標記,您可以跟蹤它。等等。有一次,你讀了一個有結束標記的塊。您剪下拳頭部分(在標記之前),將其存儲爲字符串解析。您回滾到塊的開頭,您讀取/跳過字節,直到標記之後,並且您擁有正確的二進制輸入流。 您連接累積的部分並使用'Reader'。 TBC – Marian 2009-08-27 18:25:38

+0

您需要注意橫跨兩個連續塊的結束標記。 您可以在連接之前將'byte []'作爲'List '存儲,以避免重複'System。arraycopy's 順便說一句,那100是壞的。你應該使用類似4096或16384的東西。 – Marian 2009-08-27 18:26:30

2

我認爲最好的想法是放棄「線條」的概念。要查找結束標記,請創建一個大小足以容納結束標記的ring buffer,逐字節讀入,並在每個字節後檢查它是否包含標記。

還有更復雜和高效的搜索算法,但區別只在於較長的搜索條件(可能您的結束標記很短)。

+0

我不認爲他可以選擇文件格式。 我看到了他描述的那種文件。例如,我相信用於Linux的Java2SE安裝工具包以相同的方式存儲。 – Marian 2009-08-27 14:27:01

+0

我並不是說他必須改變文件格式,只是他不應該嘗試一次讀取一個字節,而不是依賴於「行」的概念。 – 2009-08-27 14:29:54

+0

@michael:有沒有一個標準的java類環緩衝區?搜索「環形緩衝區java」後找不到相應的java網站 – sepiroth 2009-08-27 14:33:59