我有一个方法被另一个类调用,该方法对一组对象执行许多步骤。具体来说,我正在将文件列表从原始位置复制到新文件夹。复制文件后,我使用与该组文件相关的其他数据更新数据库。它看起来像这样:
public void copyFilesAndStore(File[] files, DataObject additionalData){
for (File f in files){
copyFileToDestination(f);
}
updateDatabase(additionalData);
}
问题是,如果其中一个文件出现问题,copyFileToDestination(File f)方法可以抛出各种IOExceptions,但即使其中一个文件存在异常,我也要继续复制其余的文件,并进行调用以更新数据库。所以我可以这样做:
public void copyFilesAndStore(File[] files, DataObject additionalData){
for (File f in files){
try {
copyFileToDestination(f);
} catch (IOException ex) {
log(ex);
}
}
updateDatabase(additionalData);
}
但是,调用copyFilesAndStore()的类需要知道副本是否成功,但如果我捕获此方法中的所有异常,它将不会知道它们。做下面的事情是否有意义,或者我错过了更好的解决方案?
public void copyFilesAndStore(File[] files, DataObject additionalData){
IOException encounteredException = null;
for (File f in files){
try {
copyFileToDestination(f);
} catch (IOException ex) {
log(ex);
encounteredException = ex;
}
}
updateDatabase(additionalData);
if (encounteredException != null)
throw(encounteredException);
}
答案 0 :(得分:3)
存储异常是非常安全的(不包括一些极端情况,比如OutOfMemoryException等),但是如果你想在循环中存储可能的异常,通常最好将它们全部存储起来:
public void copyFilesAndStore(File[] files, DataObject additionalData){
List<IOException> encounteredExceptions = new LinkedList<IOException>();
for (File f in files){
try {
copyFileToDestination(f);
} catch (IOException ex) {
log(ex);
encounteredExceptions.add(ex);
}
}
updateDatabase(additionalData);
if (!encounteredExceptions.empty()) {
throw(new DelayedException(encounteredExceptions));
}
}
其中DelayedException
是您自己的自定义异常,可以存储其他异常的列表(类似于常规异常中的引起链)
答案 1 :(得分:1)
我认为抛出自己的例外更为合适,列出encounteredException
作为原因:
throw new CopyAndStoreFailedException(encounteredException);
让您的异常类型能够跟踪多个cause
异常甚至是有意义的:消费代码可能想要知道哪些特定文件无法复制,以便它可以指示对用户的问题或尝试以某种方式从问题中恢复。因此,您将自定义异常传递给encounteredExceptions
的整个列表,可以通过getter方法检索。
答案 2 :(得分:0)
不要以后重新扔掉它们 - 当然,只有第一个才能进去。我个人只是将有问题的文件名(可能是一个友好的,特定的错误字符串)存储到列表中,然后再显示它们。例如。 “文件abc.txt失败:找不到”
答案 3 :(得分:-1)
没关系,但是你只是抓住最后一个例外。您可能希望存储所有有错误的文件,然后返回列表。
public void copyFilesAndStore(File[] files, DataObject additionalData){
YourExceptionClass encounteredException = new YourExceptionClass();
for (File f in files){
try {
copyFileToDestination(f);
} catch (IOException ex) {
log(ex);
encounteredException.addFile(f);
}
}
updateDatabase(additionalData);
if (encounteredException.hasFiles)
throw(encounteredException);
}