我正在试图确保将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();
为什么呢?这次没有抛出任何异常,一切正常,为什么代码来阻塞?这次最终代码应该恢复正常吗?
由于
答案 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();
}
}
}
当然,您可能需要调整日志记录和退出条件以满足您的特定需求