代码之家  ›  专栏  ›  技术社区  ›  Cheok Yan Cheng

关闭读卡器,使输入流保持打开状态

  •  1
  • Cheok Yan Cheng  · 技术社区  · 14 年前

    目前,我有一个方法:

    void method(InputStream stream) {
        // Create UTF-8 reader by wrapping up the stream.
    }
    

    我不想让方法接受读卡器的原因是,我希望自己的方法有自己的控制权来决定应该使用哪种编码类型。

    问题是,每当我关闭读卡器时,输入流也将关闭。这不是我的意图。因为输入流由调用方“打开”。因此,输入流上的关闭操作应在调用方进行。

    是否有任何方法可以在“method”中关闭读卡器,而不关闭调用方传递的inputstream?

    谢谢。

    3 回复  |  直到 14 年前
        1
  •  4
  •   Jon Skeet    14 年前

    如果不想关闭输入流,就不要关闭读卡器。毕竟,关闭读卡器除了关闭输入流之外,没有其他用途。

    假设你的方法是关闭阅读器…如果不是的话,那就重写 close() 你自己 Reader 实施(例如衍生自 InputStreamReader 或重写 关闭() 在一个 FilterInputStream 根据其他答案应该是好的。

    编辑:评论对资源泄漏表示了一些关注。是真的 理论上 , 输入流阅读器 (这是你最可能使用的那种读者)可能在幕后做些别的事情……例如,将输出写入文件。事实上,这根本不可能发生。 关闭() 只是要关闭流(通过 StreamDecoder ,实际上-至少在JDK6实现中)。唯一涉及的非托管资源是流本身…你呢? 希望 有效地泄漏。

    对于输入流,没有“flush”这样的概念——它甚至可以做什么?除了内存中的输入流和结构,基本上没有什么可以清除的…GC会处理内存,所以您就完成了。

    使用A 过滤器输入流 是一种更清洁的方法,我肯定会承认,但 这个特定的案例 我只是不想关闭阅读器。见鬼,这就是密码 简单的 比正常情况下,因为您通常需要一个try/finally块来确保在所有情况下都将其关闭。所有的一切都可以过去。

    请注意,如果您将读卡器发布到任何其他代码,那么上面的所有逻辑都将是空的-您希望关闭读卡器以阻止其他代码在不应该使用它的情况下使用它。不过,在这种情况下,我预计您将构造读卡器,从中读取,然后让它被垃圾收集,而不是p在其他地方发布引用。

        2
  •  4
  •   whiskeysierra    14 年前

    不是很漂亮,但应该能用。

    final Reader reader = makeReader(new FilterInputStream(stream) {
    
        @Override
        public void close() {
            // we don't close
        }
    
    });
    
        3
  •  0
  •   gustafc    14 年前

    另一种选择(当然不总是适用的)是通过发送读者而不是流来规避整个过程:

    void method(Reader reader) {
        // Just read stuff!
    }
    

    …然后让调用代码担心打开和关闭读卡器。这有一个额外的好处,即您的代码不会硬连接到使用UTF-8中,而且测试起来更容易,因为您只需发送一个 StringReader .