【问题标题】:Java StringReader ready()Java StringReader 就绪()
【发布时间】:2014-05-06 03:53:21
【问题描述】:

您好,这是我在这里的第一个问题,所以如果由于某种原因不遵守规则,结果是重复的或其他什么,请告诉我(不是我一开始就失去任何声誉)

无论如何,关于 Java 提供的 StringReader 类,我实际上有 2 个问题。首先,StringReader.ready() 到底是做什么的?我可以将它用作 while 循环中的条件,以便在字符串结束时终止循环吗?阅读 java 文档并没有太大帮助(或者我可能误解了他们所说的“如果保证下一个 read() 不会阻塞输入,则返回 True”的意思)

更新:

很抱歉,我错过了read() 在字符串结束时返回 -1 的部分。无论如何,我的问题仍然是 ready() 部分。我认为这应该是检查字符串是否结束的那个?

任何帮助将不胜感激,谢谢!

Link to the actual source code

导致问题的sn-p:

while (text.ready()) {

        // Updating stringBuffer, using some sort of 'rolling hash' (or is
        // it
        // indeed rolling hash?)
        stringBuffer.deleteCharAt(0);
        stringBuffer.append((char) next);

        // The next character that follows the sequence of k characters
        next = text.read();

        // store the string form of the buffer to avoid rebuilding the
        // string for the next few checks
        String key = stringBuffer.toString();

        if (hashmap.containsKey(key)) {
            // If the hash map already contain the key, retrieve the array
            asciiArray = hashmap.get(key);
        } else {
            // Else, create a new one
            asciiArray = new int[128];
        }
        System.out.println(next);

        // Error checking on my side only, because some of the text sample I
        // used contains some characters that is outside the 128 ASCII
        // character, for whatever reason
        if (next > 127) {
            continue;
        }

        // Increment the appropriate character in the array
        asciiArray[next]++;
        // Put into the hash map
        hashmap.put(key, asciiArray);

    }

【问题讨论】:

    标签: java stringreader


    【解决方案1】:

    首先,StringReader.ready() 究竟是做什么的?

    一般的约定是,如果下一次读取不会阻塞,则返回 true。对于StringReader,这始终是正确的。

    我可以将它用作 while 循环中的条件,以便在字符串结束时终止循环吗?阅读 java 文档并没有太大帮助(或者我可能误解了他们所说的“如果保证下一个 read() 不会阻塞输入,则返回 True”的意思)

    没有。一个简单的测试表明了这一点。您应该循环直到 read() 返回 -1。请注意,您必须将 read() 的结果存储到 int 中才能正常工作。

    在我构造的 while 循环中,方法 StringReader.read() 以某种方式返回 -1。

    没有“不知何故”。这就是它应该做的。

    这是什么意思?

    这意味着流的结束。在这种情况下,您已经读取了 StringReader. 中的所有字符

    同样,Java 文档没有帮助。

    相反。 Javadoc 明确指出 read() 返回“读取的字符,如果已到达流的末尾,则返回 -1”。

    我猜这意味着字符串已经终止了

    无需猜测。这就是 Javadoc 的明确表述。

    但这意味着 ready() 方法没有做它应该做的事情!

    不,它没有。 Javadoc 没有说ready() 在流结束时返回false。你对那个声明没有任何保证。在这种情况下,它返回 true,你调用了read(),它没有阻塞。合同满意。

    【讨论】:

    • 哇一个非常详细的答案。感谢和抱歉 read() 返回 -1 部分。当我通过文档进行计划时,我错过了这一点
    【解决方案2】:

    如果您查看StringReader.ready() 方法的源代码,您可以找到答案。 StringReader 是一个装饰器类,用于使用阅读器读取 Strings。您只能通过传入 String 参数来创建 StringReader 实例。

    StringReader.ready() 将始终返回 true,并且仅在实例化时传递的 String 为 null 时才抛出 IOException

     public boolean ready() throws IOException {
         synchronized (lock) {
            ensureOpen();
            return true;
         }
     }
    
     /** Check to make sure that the stream has not been closed */
     private void ensureOpen() throws IOException {
         if (str == null)
            throw new IOException("Stream closed");
     }
    

    【讨论】:

      【解决方案3】:

      为了帮助您更好地理解这个概念,假设您的 StringReader 正在以每秒一个字符的速度从 slooooow TCP 连接读取字符序列...

      如果您随后在 while 循环中调用 StringReader.read(),则每次 read() 将等待 1 秒后返回一个字符。如果您不希望代码挂在那里等待字符进入,这可能是个问题。这时StringReader.ready() 就派上用场了。如果它返回 false,那么这意味着对 read() 的调用可能会导致代码阻塞(等待),而如果 ready() 返回 true,则意味着对 read() 的调用将立即返回一个没有阻塞/等待的值(字符或 -1)。

      现在假设所有字符已经通过连接传输,因此连接关闭,那么ready() 仍然会返回true,因为它知道它不需要等待下一个字符(因为有没有)。现在,当您调用 read() 时,它也会立即返回,但这次是 -1,表示没有更多字符。

      现在让我们回到您的代码。对于您想要实现的目标,您不需要使用ready()。相反,您的代码的第一行应更改为:

      int ch;
      
      while (true)
      {
          ch = text.read();
          if (ch < 0) break;
      
          ...
      

      【讨论】:

      • (1) 返回 false 并不意味着对 .read() 的调用会阻塞。 Javadoc 明确表示相反。 (2) 返回true并不意味着read()会立即返回一个字符。这就是问题所在。它可能返回 -1 表示流结束。
      • 这里,我将“will”改为“may”,将“character”改为“value”。快乐的?在所有实际目的中,您实际上可以假设它是“意志”。 Javadoc 说返回 false 并不意味着对 read() 的下一次调用将阻塞的原因是因为当您调用 read(),一个字符可能已经可用并因此准备就绪。跨度>
      • 我明白了。我想我把 BufferedReader 和 StringReader 弄混了(或者更确切地说,我认为它们是相似的)。谢谢您的回答!抱歉,我没有足够的声望点,所以无法投票给你的答案哈哈
      猜你喜欢
      • 2021-07-10
      • 2019-06-29
      • 2022-12-03
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 2016-05-31
      • 1970-01-01
      • 2011-03-11
      相关资源
      最近更新 更多