【问题标题】:Java InputStream != ReadableJava InputStream != 可读
【发布时间】:2010-01-08 23:03:00
【问题描述】:

我正在使用 java.util.Scanner 来处理诸如 nextInt() 之类的事情,只要我使用 java.lang.Readable(一个也是唯一的构造函数参数),一切都可以正常工作。但是,当我改为使用 InputStream 时, Scanner.nextInt() 永远不会返回。你知道为什么吗?

我的 InputStream 实现如下所示:

private static class ConsoleInputStream extends InputStream {
    ...
    private byte[] buffer;
    private int bufferIndex;
    public int read() throws IOException {
        ...
        while (...) {
            if (buffer != null && bufferIndex < buffer.length) {
                return buffer[bufferIndex++];    // THE COMMENT!
            }
            ...
        }
        ...
    }
}

当我通过 THE COMMENT 打印数据时,我(正确地)得到诸如“12\n”的“1”、“2”、“\n”之类的东西。是否有一些扫描仪连接,我不知道,那个导致这种行为?

【问题讨论】:

  • 为什么要在字节级别而不是字符级别执行此操作?

标签: java inputstream java.util.scanner


【解决方案1】:

来自 InputStream 的 read() 方法的 javadocs:

“返回:数据的下一个字节,如果到达流的末尾,则返回 -1。”

我猜你永远不会返回 -1?

【讨论】:

  • 我认为这意味着流的“永久”结束(如“不要再读我”),而不仅仅是一个“分隔符”(如换行)。
  • 通常情况下,-1 是节目的结束。如果流突然改变主意,我不确定流的消费者会如何反应。
  • 我以为我也在某个地方看到过。 (但现在它正在起作用,所以我将继续我的“从不信任文档”的态度。:)
  • @Jonas - 你不必相信文档。您可以阅读Java类库的源代码!
【解决方案2】:

我认为问题出在您自建的 InputStream 上。为什么您要自己构建,而不是简单地使用 System.in?

更新:

需要来自 JTextField 的输入。

好的,知道了。使用 I/O 处理以字符形式读取已经可用的内容通常没有意义,但我可以看到使用 Scanner 可以让您的生活更轻松。

不过,您可能通过使用“已完成”的 InputStream 为自己节省了一些编码和痛苦。想到的是

InputStream is = new ByteArrayInputStream(myTextField.getText().getBytes());

Java I/O 很糟糕。很高兴来自 Sun 的聪明人已经为您封装了大部分内容。

【讨论】:

  • 需要来自 JTextField 的输入。
  • 听起来很合理,尽管我需要为我的 jar 用户提供静态(持久)InputStreams 和 Scanners。
  • 我听到了。但我想给你灌输一种真正的内疚感,因为你使用了本质上未定义的行为。输入流改变其是否处于 EOF 的想法并不是一个好主意,并且您的代码可能会在未来的 JVM 上失败,并且您将在调试时花费大量时间诅咒自己。
  • 我敢打赌这是一个未记录的功能;这种变化会在数百万用户中造成严重破坏。
  • 不,我认为不是那种功能。它看起来更像是一个疏忽。老实说,我相信您所做的事情非常不寻常,因此不太可能受到历史先例的保护。但我现在要放弃了;)
猜你喜欢
  • 2011-09-03
  • 2010-10-11
  • 1970-01-01
  • 2016-04-29
  • 2014-07-01
  • 1970-01-01
  • 2013-04-16
  • 2011-06-29
  • 2021-07-02
相关资源
最近更新 更多