即使没有抛出异常,代码也会进入catch块

时间:2013-05-15 09:03:47

标签: java

我正在试图确保将url中的内容成功写入文件。为此,我使用以下代码

public void copyFileFromUrl(URL source, File target, int count) throws IOException {

    InputStream in = null;
    OutputStream out = null;

    if (target != null) {
        try {       
            if (!target.exists()) {
                target.createNewFile();
                log.debug("target file created for " + target);
                log.debug("downloading source .... " + source);

                if (source == null) {                   
                    log.debug("Null source .... " + ScormFileWriter.class.getName());
                    return;         
                } else {    
                    in = source.openStream();   
                }   
                out = new FileOutputStream(target);

                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }

                log.debug("The contents from the URL: " + source + " are successfully written to the file " + target);

            } else {
                log.debug("skipping creation of asset");
            }

        } catch (Exception e) {

            if(count < 3){
                log.debug("trouble with " + target);
                if (in != null) {       
                    in.close(); 
                }
                if (out != null) {  
                     out.close();   
                }

                // Attempt to delete it
                boolean success = target.delete();

                if (!success) { 
                    log.debug("Unable to delete " + target);    
                } else {
                    copyFileFromUrl(source, target, ++count);   
                }               
            }

            log.debug("trouble in downloading source after trying " + count +  " times: " + source);
            e.printStackTrace();        
        } finally {         
            if (in != null) {               
                in.close();             
            }           
            if (out != null) {              
                 out.close();               
            }             
        }       
    }   
}

现在,当函数进入

时首次调用时会发生什么
while ((len = in.read(buf)) > 0) {
    out.write(buf, 0, len);
}

我拔掉了我的电缆,抛出了异常并且代码来阻塞并再次调用该函数。现在我插上电缆,这次while循环完成,行

log.debug("The contents from the URL: " + source + " are successfully written to the file " + target);

打印,代码到达最后阻止,然后代码到达这两行

log.debug("trouble in downloading source after trying " + count +  " times: " + source);
e.printStackTrace();

为什么呢?这次没有抛出任何异常,一切正常,为什么代码来阻塞?这次最终代码应该恢复正常吗?

由于

1 个答案:

答案 0 :(得分:2)

您递归调用该方法。第一次抛出异常时,代码将再次调用自身,直到执行线程从第二次调用方法返回时才会到达打印行。一旦方法正确完成,执行将返回到第一个&#34;实例&#34;该方法和执行的方法落到印刷线上。我认为更好的方法是循环尝试获取文件而不是递归调用相同的方法。如果你必须递归地调用它,请确保方法在重新调用之前执行它所需的所有操作,执行方式。

修改
您总是可以将打印行移动到递归调用之前,这样当执行回到它时,该方法将无需执行任何操作,除非&#34; unroll&#34;递归调用。如果你想避免递归调用,我正在考虑让循环继续最多3次,但如果成功你退出循环,否则,让循环返回顶部。类似的东西:

InputStream in = null;
OutputStream out = null;

if (target != null) {
  while(n<3){
    try {       
        if (!target.exists()) {
            target.createNewFile();
            log.debug("target file created for " + target);
            log.debug("downloading source .... " + source);

            if (source == null) {                   
                log.debug("Null source .... " + ScormFileWriter.class.getName());
                return;         
            } else {    
                in = source.openStream();   
            }   
            out = new FileOutputStream(target);

            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }

            log.debug("The contents from the URL: " + source + " are successfully written to the file " + target);

        } else {
            log.debug("skipping creation of asset");
        }
        n=4; or break;
    } catch (Exception e) {


            log.debug("trouble with " + target);
            if (in != null) {       
                in.close(); 
            }
            if (out != null) {  
                 out.close();   
            }

            // Attempt to delete it
            boolean success = target.delete();

            if (!success) { 
                log.debug("Unable to delete " + target);

            } else {
               // copyFileFromUrl(source, target, ++count);
            }               

           n++;
         if(n == 2){
            log.debug("trouble in downloading source after trying " + count +  " times: " +           source);
            e.printStackTrace();        
        }
    } finally {         
        if (in != null) {               
            in.close();             
        }           
        if (out != null) {              
             out.close();               
        }             
    }       
  }

当然,您可能需要调整日志记录和退出条件以满足您的特定需求