1

我很想确保 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);

打印,代码来到 finally 块,然后代码来到这两行

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

为什么?这次没有抛出异常,一切正常,为什么代码来了 catch 块?这个时候finally之后代码应该恢复正常了吧?

谢谢

4

1 回答 1

2

您正在递归调用该方法。第一次抛出异常时,代码分叉并再次调用自身,直到执行线程从第二次调用该方法返回时才到达打印行。一旦该方法正确完成,执行将返回到该方法的第一个“实例”并执行到打印行。我认为更好的方法是循环尝试获取文件,而不是递归调用相同的方法。如果您必须递归调用它,请确保方法完成了它需要做的所有事情,明智地执行,然后再次调用自身。

编辑
您始终可以将打印行移动到递归调用之前,这样当执行返回到它时,该方法将无事可做,除非“展开”递归调用。如果你想避免递归调用,我正在考虑让循环最多进行 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();               
        }             
    }       
  }

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

于 2013-05-15T09:14:14.300 回答