gpt4 book ai didi

java - 在 try catch block 中未捕获多个 IOException 子类

转载 作者:行者123 更新时间:2023-11-30 04:33:07 26 4
gpt4 key购买 nike

我正在使用以下方法从服务器下载图像以在 Android 应用程序中提供服务。

public static void downloadToFile(File file, URL url, int connectTimeout, 
int readTimeout) throws IOException {
InputStream in = null;
OutputStream out = null;
try {
URLConnection ucon = url.openConnection();
ucon.setConnectTimeout(connectTimeout);
ucon.setReadTimeout(readTimeout);

in = ucon.getInputStream();
out = new FileOutputStream(file);
byte[] buffer = new byte[BUFFER_SIZE];
int count = 0;
while ((count = in.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
out.flush();
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}

当文件已从服务器中删除但我仍然尝试下载它时,我收到一个 FileNotFoundException,这是完全有效的。在我的应用程序中,对此方法的调用包含在处理 IOException 和 Exception 的 try catch 中,因此我可以继续。

问题是在 Android Developer Console 中我收到了一些崩溃报告,并且 FileNotFoundException 似乎忽略了 catch block 并强制关闭了应用程序。

java.io.FileNotFoundException: http://foo.org/1234.jpg
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1162)
at com.package.IOUtil.downloadToFile(Unknown Source)

未知来源是因为 Proguard 但我可以在测试时通过放入不存在的文件 URLS 来强制异常,这确实会引发异常。当我在手机 (SGS2 2.3.3) 和平板电脑 (TF101 3.2) 上进行测试时,try catch block 确实捕获了异常。下面的堆栈跟踪指向 URL#getInputStream() 作为抛出异常的原因,但这并不能解释为什么它没有被某些(只有少数)捕获。

java.io.FileNotFoundException: http://foo.org/1234.jpg
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:521)
at com.package.IOUtil.downloadToFile(IOUtil.java:142)

我也遇到过相同的问题,即来自同一方法/被调用方的 SocketException 未被捕获。

java.net.SocketTimeoutException: Connection timed out
at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method)
at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:357)
at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:204)
at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:437)
at java.net.Socket.connect(Socket.java:1002)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>(HttpConnection.java:75)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.<init>(HttpConnection.java:48)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection$Address.connect(HttpConnection.java:322)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnectionPool.get(HttpConnectionPool.java:89)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getHttpConnection(HttpURLConnectionImpl.java:285)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.makeConnection(HttpURLConnectionImpl.java:267)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.retrieveResponse(HttpURLConnectionImpl.java:1018)
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:512)
at com.package.IOUtil.downloadToFile(Unknown Source)

如果重要的话,下载是在后台线程中完成的。

我错过了什么吗?它可能是特定于电话的,还是 Proguard(即使它几乎被其他所有人捕获)?

编辑:捕获的代码

private void download(List<URL> urls, int attempts) {
List<URL> failedDownloads = new ArrayList<URL>();
for (URL url : urls) {
if (isInterrupted()) {
return;
}

String imageName = Util.getImageName(url);
File cacheFile = cache.getCacheFile(imageName);
try {
// Bad downloads often don't throw an IOException but
// leave the file with a length of 0.
if (cacheFile.length() == 0) {
Util.safeDelete(cacheFile);
}

if (!cacheFile.exists()) {
IOUtil.downloadToFile(cacheFile, url);

if (cacheFile.length() == 0) {
//See above
Util.safeDelete(cacheFile);
failedDownloads.add(url);
} else {
if (putToCache) {
cache.get(imageName);
}
handler.sendEmptyMessage(0);
}
} else {
// Exists already, move it to cache
if (putToCache) {
cache.get(imageName);
}
}
} catch (IOException ioe) {
Util.safeDelete(cacheFile);
failedDownloads.add(url);
} catch (Exception e) {
// Continue on to next download - don't bother trying this
// URL again.
}
}

if (!failedDownloads.isEmpty() && attempts < maxAttempts) {
attempts++;
download(failedDownloads, attempts);
}
}

Util.safeDelete 只是一个包含在 try catch 中的删除,因此不应该相关。

最佳答案

首先,不要捕获和压缩 Exception不要这样做。 永远不要。如果出现意想不到的错误,您将丢弃所有证据。

其次,重新编译包含调试信息的代码,您将在堆栈跟踪中获得您的方法的文件名和行号。在开发/测试时摆脱 Proguard。 (最好完全摆脱它,因为它不会给你任何真正的保护。)

最后,download 方法(正如您复制的那样)不可能导致未捕获的 IOException。如果是:

  • 你显然确实捕获了异常,并且
  • 该方法会出现编译错误,因为它没有声明 IOException,并且
  • download 方法将成为堆栈跟踪的一部分,并且

因此它一定是类似...

  • 您已声明另一个 IOException 类并将其导入到该文件中,或者
  • 罪魁祸首是您的 safeDelete 方法,或者
  • download 方法被重载并且异常发生在不同的重载中,或者
  • 您正在 download 之外的某处调用 downloadToFile,或者
  • 您复制的代码不准确,或者
  • 您在编译/部署代码时犯了一个错误;例如编辑后忘记重新编译。

关于java - 在 try catch block 中未捕获多个 IOException 子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7345349/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com