我有一个Scanner链接到System.in。现在,在使用Scanner之后,我应该将其关闭,因为将其保持打开状态是不好的编码习惯。但是,如果我关闭Scanner,我也将关闭System.in!谁能告诉我如何关闭Scanner而不关闭System.in(如果有任何方法)。

评论

stackoverflow.com/questions/5919143/…希望这对您有用。我仍在寻找System.in是否可实现关闭。如果没有,那么您就一清二楚了。

请注意,您可以使用装饰器保护流。

是的,System.in确实实现了closeable。

@pauljerman System.in是一个InputStream,因此实现了AutoClosable,请参阅文档。

“医生,我这样做会很痛!” ...“那就不要那样。”

#1 楼

一种选择是将System.in流包装在CloseShieldInputStream中,以防止其被关闭。然后,您的读者将使用CloseShieldInputStream而不是原始的System.in流。

这是该类的API:
http://commons.apache.org/io/apidocs/org/ apache / commons / io / input / CloseShieldInputStream.html

评论


您还可以为System.in流创建自己的自定义不可关闭包装器

–保罗·杰曼
13年1月3日在16:33

#2 楼

最简单的方法是,如果您不想关闭基础流,则不关闭扫描仪。

理想情况下,您应该只创建一个在程序生命周期内使用的扫描仪。无论如何,看来您没有充分的理由将其关闭。

评论


通过要求代码知道它正在与系统对话或至少不应该关闭的对话来工作。 Paul Jermans对CloseShieldInputStream的建议允许代码忽略该事实,并像对待其他任何InputStream一样简单地对待它,并在完成时尝试将其关闭。这里简单的事情实际上取决于上下文。

–candied_orange
16年11月26日在18:07

@candied_orange您不应关闭自己不拥有的流(鉴于Java中缺乏强烈的所有权概念,这大致意味着您没有打开)。如果您从其他地方接收到流,请不要关闭扫描仪。

–安迪·特纳(Andy Turner)
18-10-12在6:55

@AndyTurner有效。如果您想遵循该规则并且仍然可以自由使用,请在中间模式中查找孔

–candied_orange
18-10-12在13:43

#3 楼

除了添加诸如此类的屏蔽类之外,只需添加一个漂亮的注释和一个

        @SuppressWarnings("resource")


就足够了。而且我似乎没有看到这种方法有很多缺点。不要忘记评论。

评论


?这可能会阻止警告,但不会阻止您获取IOException:在关闭扫描器后尝试使用System.in时,流已关闭。

–derHugo
18/12/14在13:38

@derHugo我认为它们的意思是不要关闭扫描仪,并用批注抑制有关此警告,并添加解释性注释。

– bkis
19年1月15日在13:54

#4 楼

我很久以前就对奇怪的,无法诊断的问题有模糊的记忆,因为两次使用相同的ScannerSystem.in,所以这就是我所使用的(即使您在程序运行期间可能只使用一个扫描仪):

static String input() {
    try {
        return new Scanner(System.in).nextLine();
    } catch (NoSuchElementException e) {
        throw e;
    }
}


由于某种原因,它在没有警告的情况下仍然有效,但是如果我不进行掷球,Eclipse会抱怨Resource leak: '<unassigned Closeable value>' is never closed

评论


您只是通过在这里混淆Eclipse代码分析来避免警告:)扫描器仍然从未关闭(不是您应该这样做):)

–john16384
17-2-28在8:44



#5 楼

根据InputSteam的API,“ InputStream的close方法不执行任何操作。”,因此,由于System.in是InputStream的实例,因此您不必担心在其上调用close()。

评论


显然,事实并非如此。如果我在System.in上打开扫描仪,将其关闭,然后打开另一个然后尝试使用它(例如nextLine()),则会收到NoSuchElementException。

– Blrp
15年11月6日在18:17

尽管close()在抽象InputStream的默认实现中确实没有执行任何操作,但这并不意味着所有子类都适用!如果是这样,则该方法将无用。

–吉里·托瑟克(Jiri Tousek)
16年1月8日在16:27

InputStream是一个抽象类。当子类表示使用后需要关闭的资源(例如stdin)时,它们可以并且应该“做某事”。可以在InputStream.close()中将其弄清楚,但是您的结论不正确。

–dimo414
16-2-26在18:51

这个答案是完全错误的,我认为需要删除

– aristotll
9月16日下午3:13