4

我有一个方法被另一个类调用,该类对对象集合执行多个步骤。具体来说,我将文件列表从其原始位置复制到一个新文件夹。复制文件后,我使用与文件组相关的附加数据更新数据库。它看起来像这样:

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);
}
4

4 回答 4

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可以存储其他异常的列表(有点像常规异常中的引起链)

于 2012-04-12T01:22:49.097 回答
1

我认为抛出你自己的异常会更合适,列为encounteredException原因:

throw new CopyAndStoreFailedException(encounteredException);

让您的异常类型能够跟踪多个cause异常甚至可能是有意义的:消费代码可能想知道哪些特定文件无法复制,以便它可以向用户指示问题或尝试恢复以某种方式解决问题。因此,您将自定义异常传递给整个列表encounteredExceptions,可以通过 getter 方法检索该列表。

于 2012-04-12T01:19:13.337 回答
0

以后不要再扔它们,当然——无论如何,只有第一个会扔掉。我个人只是将有问题的文件名(可能还有一个友好的、特定的错误字符串)存储到一个列表中,然后再显示它们。例如。“文件 abc.txt 失败:未找到”

于 2012-04-12T01:17:12.743 回答
-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);
}
于 2012-04-12T01:22:02.883 回答