Reading extension, how to return my "reading"?

As part of my Java course, I wrote a β€œzip” to the writer and reader - how the Huffman algorithm works.

My class extends Reader and has a Reader r object. In my main method, I have the following lines:

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

It should return the unpacked string that I wrote to the file, after decompressing it, of course. But it returns the first line of the file!

My reading function:

 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; } 

My Debug window shows the following:

 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 

It calls my read function twice. How can I stop bufferReader from calling the read function again?

+5
source share
2 answers

You do not return the data that you read from the method, as usual. Instead, when read is called, the calling server gives you the cbuf array, which is essentially the address of the memory block, and tells you to write len char .

When you do cbuf = fnlStr.toCharArray() , you simply replace your local copy of this address with a different address, but you do not actually change the memory you were supposed to write to. You need to either iterate over the array that you specified in the for loop and write to it, or use System.arraycopy if you created another buffer containing the result.

For example, the following read method will always 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; } 

Replacing the literal "Test\n" your unpacked line, you should start. Of course, you still have to control how much of your source you already consume.


As for the BufferedReader calling read twice: you don't care how often it calls. Just get the data from your original source, write it to cbuf and return the char number you wrote. If there is nothing to read, return -1 to signal the end of the stream (in this case, BufferedReader will stop calling read ).


As an aside, Reader designed to read character streams, while an InputStream is for binary data (this is basically the same, only with byte[] instead of char[] and without using encoding). Since compressed files are binary, you can switch your FileReader to FileInputStream .

I could imagine strange errors if, for some reason, the encoding you are encoding is different from the one with which you are decoding. Or less dramatically, you can use more space than you think if one 16-bit code in UTF-16 needs 3 8-bit code modules in UTF-8.

+2
source

You read only the first line. Change the first part to something like:

 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); } 

And also, to fix the fact that your method is called twice, enter a boolean value and set it to true after you have completed your actions in the method. Then at the beginning of this method, check to see if this is a boolean. If so, return from the method so that it does not do things after it.

+1
source

All Articles