2012-12-03 42 views
2

所以。我正在尝试在Android上做一些网络内容。在我的异步任务,我做: 在Android中关闭输入流(Java)

InputStream streamOfDestiny = null; 

try{ 
    // do some network stuff here... 
} 
finally{ 
    if(streamOfDestiny != null){ 
     streamOfDestiny.close(); // Build error here. Apparently, closing a stream can cause an IOException. Why this is the case, I do not know. But it is. And, since this is Java, I apparently need to care. 
    } 
} 

所以,现在我有了这个IOException异常结垢一切。我可以这样做:

InputStream streamOfDestiny = null; 

try{ 
    // do some network stuff here... 
} 
finally{ 
    if(streamOfDestiny != null){ 
     try{ 
      streamOfDestiny.close(); 
     } 
     catch(IOException e){ 
      // Hey look! I'm inside a catch block, inside a finally block! 
     } 
    } 
} 

但这看起来很糟糕。 finally块中的try/catch块?多丑!我可以让它保持封闭,但这对我来说似乎是不好的练习,只是感觉不对(我开始了这个流,我想完成它)。我可以这样做:

IOUtils.closeQuietly(streamOfDestiny); 

但现在我必须找到org.apache.commons.io.IOUtils并以某种方式包含了我的包。太多的工作,加上我的包装大小,我只需要一个功能。瘸。

我总是可以写我自己的closeQuietly的版本:

public static void closeStreamQuietly(InputStream streamToClose){ 
    try{ 
     streamToClose.close(); 
    } 
    catch (IOException e){ 
     // ignore it.... 
    } 
} 

但只是好像我重新发明轮子,这几乎总是坏消息 - 感觉,就必须有一些不错,优雅的做法,我完全不在这里。

任何想法的人?

回答

0

我不确定你为什么要把你的选项-2(try-catch块内部)或者选项-4(创建一个小的util方法)称为丑陋或额外的工作。这是正常的和预期的。

如果您正在finally内编写任何代码,则应该完成相关的异常处理,这里就是这种情况。

通过加入null检查,您已完成一项异常处理(预防性),否则当streamOfDestiny为空时,可能会抛出NullPointerException

第二异常处理需要处理的流关闭例外情形中,其可以与所述的原因,如出现流是not openunavailableit's not able to release the underline resources或场景,如this

+0

我不知道 - 也许是我,但是finally块代表应该总是执行的代码,try块是专门处理异常的代码,导致代码不被执行。我意识到这并不适用于这种情况,但我仍然不喜欢它。 选项4并不可怕,但我只是期待框架能够在某个地方处理过这个问题......再次感觉就像重新发明了轮子? 我知道这篇文章的大部分内容都是主观的 - 也许过于风格化......但是,嘿,我只是想看看我是否错过了这里的东西。 – mschultz

+0

@ user1864042这不是重新发明轮子。最后,block是为了执行你认为应该运行的那段代码,即使发生了一些异常。这并不意味着你可以在最后放置任何代码,Java将自己处理预期的异常。简而言之,'finally'块和异常处理是两个不同的概念。不要混合它们。如果你在finally块中编写了一些代码,相关的异常处理应该明确地完成。无论您是在块内部执行该操作,编写自定义方法,使用某个框架还是作为抛出声明等,都取决于您。 –

+0

@Yogndra - 我明白了你的观点....我想这一切都归结为我仍然不明白为什么close应该抛出异常 - 而且我认为框架应该提供一种方法来关闭IO流在不抛出任何东西的情况下,一种实现逻辑的方法“我在这里有这个IOStream对象,我不再希望使用它,请关闭它,让它停止它做的任何事情,释放它使用的任何资源(连接等) ,然后让我继续我的快乐之路“。 – mschultz

0

没有神秘感。 close()在大多数实现中调用flush()(请参阅Javadoc的FilterOutputStream),而flush()可能会抛出IOException,,因为它可能会执行I/O。其他可能性是可以想象的。

0

您应该使用资源尝试。

try (InputStream streamOfDestiny = ...) { 
    //Do you networking stuff 
} catch (IOException ioe) { 
    //Handle the exceptions 
}