首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试使用资源和System.in

尝试使用资源和System.in
EN

Stack Overflow用户
提问于 2014-04-13 09:52:22
回答 3查看 1.3K关注 0票数 4

好吧,这可能不是最好的问题,但我被困住了,在网上找不到答案。

此代码不会第二次从标准输入中读取:

代码语言:javascript
复制
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))
{
    input = br.readLine();
}
catch (final Exception e)
{
    System.err.println("Read from STDIN failed: " + e.getMessage());
}
// do some processing
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))
{
    input = br.readLine();
}
catch (final Exception e)
{
    System.err.println("Read from STDIN failed: " + e.getMessage());
}

我知道java的“使用资源的尝试”递归地关闭了链中的所有流,所以在第一次读取System.in之后就关闭了。有什么好的解决办法吗?还是我真的应该处理好自己关闭的溪流?

upd:我试图自己关闭流(即java6 6风格)。如果有人感兴趣,这里有一个代码。但我注意到,这种关闭链的行为并非来自于资源的尝试,而是来自于关闭方法的实现。所以我从那次尝试中什么都没赢。

我选择fge的解决方案,因为它是最冗长的解决方案。它直接对我起作用。

总之,我觉得很奇怪,java没有这样的解决方案,因为有一些不应该关闭的系统流。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-13 09:56:46

解决方法之一是创建一个自定义的InputStream类,它将委托给另一个类,但当它本身关闭时,它不会.close()。如:

代码语言:javascript
复制
public class ForwardingInputStream
    extends InputStream
{
    private final InputStream in;
    private final boolean closeWrapped;

    public ForwardingInputStream(final InputStream in, final boolean closeWrapped)
    {
        this.in = in;
        this.closeWrapped = closeWrapped;
    }

    public ForwardingInputStream(final InputStream in)
    {
        this(in, false);
    }

    @Override
    public int read()
        throws IOException
    {
        return in.read();
    }

    @Override
    public int read(final byte[] b)
        throws IOException
    {
        return in.read(b);
    }

    @Override
    public int read(final byte[] b, final int off, final int len)
        throws IOException
    {
        return in.read(b, off, len);
    }

    @Override
    public long skip(final long n)
        throws IOException
    {
        return in.skip(n);
    }

    @Override
    public int available()
        throws IOException
    {
        return in.available();
    }

    @Override
    public void close()
        throws IOException
    {
        if (closeWrapped)
            in.close();
    }

    @Override
    public synchronized void mark(final int readlimit)
    {
        in.mark(readlimit);
    }

    @Override
    public synchronized void reset()
        throws IOException
    {
        in.reset();
    }

    @Override
    public boolean markSupported()
    {
        return in.markSupported();
    }
}

请注意,在您的情况下,一个可能更容易的解决方案是扩展InputStreamReader,因为该类不是final,而只是覆盖.close()

票数 1
EN

Stack Overflow用户

发布于 2014-04-13 10:05:58

我认为这个问题比尝试资源更普遍,因为其他人可能会使用较旧版本的Java,并自行关闭BufferedReader。这会让你和现在一样陷入同样的境地。

我为这个更一般的情况找到了一个相关问题。给出的答案是使用Apache,它有一个名为CloseShieldInputStream的流代理。如果这是您要使用的Commons中的唯一东西,您还可以考虑自己编写代理类,而不是依赖于一个大型库,比如Commons。

票数 1
EN

Stack Overflow用户

发布于 2017-02-28 05:16:25

这是一个老问题,但这里有一个更简洁的解决方案:

代码语言:javascript
复制
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in)
{public void close() throws IOException {}})) {
    input = br.readLine();
}

这确保System.in不会通过向BufferedReader的构造函数传递带有空重写的close()方法的close()来关闭。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23041258

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档