作为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函数?
您不会像通常那样返回从该方法读取的数据。而是在read
调用时,调用方为您提供array cbuf
,它实际上是一块内存的地址,并告诉您将len
char
s写入其中。
当您这样做时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
已写入的s的数量即可。如果没有什么要读取的内容,则返回-1
信号流结束(在这种情况下BufferedReader
将停止调用read
)。
顺便说一句,Reader
它用于读取字符流,而InputStream
用于二进制数据(基本上是同一件事,只是使用byte[]
代替char[]
和不使用字符集)。由于压缩文件是二进制文件,因此您可能需要将其切换FileReader
为FileInputStream
。
如果由于某种原因,您使用的编码字符集与您解码时使用的字符集不同,我可以想象出奇怪的错误。或者说,如果UTF-16中的一个16位代码单元需要UTF-8中的3个8位代码单元,则可能会使用比您想象的更多的空间。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句