2015-04-30 46 views
5

作爲我的Java課程的一部分,我編寫了一個「zip」作家和讀者 - 與霍夫曼算法一樣。擴展閱讀器,如何返回我的「閱讀」?

我的課程擴展了Reader,並有一個對象Reader r。 在我的主要方法,我有這行:

input = new BufferedReader(new HuffmanReader(new FileReader("output.hff"))); 
String str = input.readLine(); 

它應該返回字符串解壓我寫的文件,解壓縮它,當然之後。但它返回文件的第一行!

我讀功能:

public int read(char[] cbuf, int off, int len) throws IOException { 
    //... 
    r.read(buffer,0,8192) 
    //does the decompress process 
    String fnlStr = ... //The final result 
    cbuf = fnlStr.toCharArray(); 
    //close streams 
    return cbuf.length; 
} 

我的調試窗口顯示了這一點:

HuffmanReader.read(char[], int, int) line: 23 
BufferedReader.fill() line: not available 
BufferedReader.readLine(boolean) line: not available  
BufferedReader.readLine() line: not available 
Run.main(String[]) line: 23 

它要求我讀功能的兩倍。如何停止bufferReader再次調用read函數?

+0

1.您在'read()'函數中考慮過'off'和'len'嗎? 2.你需要這個BufferedReader嗎(你不能沒有它測試)? – xerx593

+1

您從'input'中讀取的唯一地方是在'input.readLine()'中,它自然只讀取一行。我有點驚訝,你的'read'函數完全可以工作,因爲你實際上並沒有寫入傳入的緩衝區,而只是給'cbuf'分配一個新的緩衝區。 – dddsnn

+0

你也不會使用'r.read()返回的計數。「這段代碼不可能工作。 – EJP

回答

2

您不像通常那樣返回從方法中讀取的數據。相反,當調用read時,調用者會爲您提供數組cbuf,它實際上是一塊內存的地址,並告訴您將lenchar寫入其中。

當你做cbuf = fnlStr.toCharArray(),你只是用另一個地址替換你的本地地址副本,但實際上並沒有改變你應該寫入的內存。您需要迭代在for循環中給出的數組並寫入該數組,或者如果您構建了包含結果的另一個緩衝區,則使用System.arraycopy

例如,下面的read方法將總是讀"Test\n"

public int read(char[] cbuf, int off, int len) throws IOException { 
    char[] result = "Test\n".toCharArray(); 
    int numRead = Math.min(len, result.length); 
    System.arraycopy(result, 0, cbuf, off, numRead); 
    return numRead; 
} 

更換"Test\n"文字與解壓縮字符串應該讓你開始。當然,你仍然需要管理你已經消耗了多少資源。


並作爲BufferedReader調用read兩次:你不應該關心它是如何經常被稱爲。只需從您的基礎來源獲取數據,將其寫入cbuf並返回您編寫的數量char。如果沒有剩下可讀的內容,則返回-1來表示流結束(在這種情況下BufferedReader將停止呼叫read)。


順便說一句,Reader是爲了讀取字符流,而InputStream is for binary data(它基本上是同樣的事情,只是byte[]代替char[]和不使用的字符集)。由於壓縮文件是二進制文件,因此您可能需要將FileReader切換爲FileInputStream

我可以想象,如果出於某種原因,您編碼的字符集與您解碼的字符集不一樣,那麼可能會出現奇怪的錯誤。如果UTF-16中的一個16位代碼單元需要UTF-8中的3個8位代碼單元,則可能會比您想象的要更多空間。

+0

非常感謝!那是我的問題。它運作良好! 我知道讀者的問題,這是我們對這個練習的限制。謝謝。 –

1

您正在閱讀的第一條線。第一部分更改爲類似:

input = new BufferedReader(new HuffmanReader(new FileReader("output.hff"))); 
Arraylist<String> list = new ArrayList<String>(); 
String line; 

while ((line = reader.readLine()) != null) { 
    list.add(line); 
} 

而且也,來修復你的方法被調用了兩次,做一個布爾值,並將其設置爲true,你在方法中完成你的東西了。然後在該方法的開始,檢查該布爾值是否爲真。如果是這樣,從方法返回,所以它不會在它再次執行之後執行。

+0

或者只是調用一次方法;-) – EJP

+0

@ ImBatman64嗨,我早些時候嘗試過布爾事物,它不起作用,因爲我不知道如何將結果寫入緩衝區。當它下一次出現時,它返回String str一個包含一些空格的字符串。我無法改變主要部分 - 這是練習的一部分。 BufferedReader試圖再次讀取,但它應該只讀取一行。 –

+0

@RoeiJacobovich你究竟在哪裏調用該方法? – ImBatman64