【问题标题】:Extending reader, how to return my "read"?扩展阅读器,如何返回我的“阅读”?
【发布时间】:2015-07-10 18:12:02
【问题描述】:

作为我的 Java 课程的一部分,我编写了一个“zip”编写器和阅读器 - 就像 Huffman 算法一样。

我的类扩展了 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 函数?

【问题讨论】:

  • 1.您是否在您的read() 函数中考虑了offlen? 2. 你需要那个 BufferedReader(没有它就不能测试吗)?
  • 您从input 读取的唯一位置是input.readLine(),它自然只读取一行。我有点惊讶您的 read 函数完全起作用,因为您实际上并没有写入传入的缓冲区,您只需为 cbuf 分配一个新缓冲区。
  • 你也没有使用r.read().返回的计数这个代码不可能工作。
  • 当我从文件中读取时,我正在读取到临时缓冲区直到 8192 个字符。它有超过 8192 个,它将它复制到传递给解压缩函数的字符串并读取下一个字符。我不能改变主 - 作为练习的一部分。我不知道如何写入我的 BufferedReader - 这就是我所要求的。

标签: java


【解决方案1】:

您不会像往常那样返回从方法中读取的数据。相反,当调用read 时,调用者会为您提供数组cbuf,它本质上是一块内存的地址,并告诉您将len chars 写入其中。

当您执行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 并返回您写入的chars 的数量。如果没有内容可读取,则返回 -1 以指示流结束(在这种情况下,BufferedReader 将停止调用 read)。


顺便说一句,Reader 用于读取字符流,而InputStream is for binary data(基本上是一样的,只是使用byte[] 而不是char[],并且不使用字符集)。由于压缩文件是二进制文件,您可能需要将 FileReader 切换为 FileInputStream

如果出于某种原因,您编码时使用的字符集与解码时使用的字符集不同,我可以想象会出现奇怪的错误。或者,如果 UTF-16 中的一个 16 位代码单元需要 UTF-8 中的 3 个 8 位代码单元,您可能会使用比您想象的更多的空间。

【讨论】:

  • 非常感谢!那是我的问题。它运作良好!我知道 Reader 的问题,这是我们对这个练习的限制。谢谢。
【解决方案2】:

您只阅读第一行。将第一部分更改为:

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。然后在该方法的开头,检查该布尔值是否为真。如果是,则从该方法返回,这样它就不会再执行它之后的事情了。

【讨论】:

  • 或者只调用一次方法;-)
  • @ImBatman64 嗨,我之前尝试过布尔值,但它不起作用,因为我不知道如何将结果写入缓冲区。下次来的时候,它会返回给 String str 一个带有一些空格的字符串。我不能改变主要部分——这是练习的一部分。 BufferedReader 正在尝试再次读取,尽管它应该只读取一行。
  • @RoeiJacobovich 你到底在哪里调用这个方法?
  • @ImBatman64 就像我在上面写的主要部分一样。我的 input.readLine() 两次调用我的读取函数。
  • RoeiJacobovich 你能把完整的源代码贴在某个地方让我测试一下吗?这会很有帮助。
猜你喜欢
  • 2015-05-01
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多