簡體   English   中英

即使沒有引發異常,代碼也會進入catch塊

[英]code is coming in catch block even if no exception is thrown

我要確保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);
}

我拔下電纜,拋出異常,代碼進入catch塊並再次調用該函數。 現在我插入電纜,這次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();

為什么? 這次沒有拋出異常,一切正常,為什么代碼來捕獲塊? 這段時間之后代碼終於應該恢復正常了嗎?

謝謝

您正在遞歸調用該方法。 第一次拋出異常時,代碼會分叉繼續並再次調用自身,直到執行線程從第二次調用該方法返回之前,打印行才到達。 一旦方法正確完成,執行將返回到該方法的第一個“實例”,並且執行將進入打印行。 我認為更好的方法是遍歷獲取文件的嘗試,而不是遞歸調用相同的方法。 如果必須遞歸調用它,請確保在再次調用自身之前,方法應明智地執行這些方法。

編輯
您始終可以將打印行移動到遞歸調用之前,這樣,當執行返回到該方法時,除了“展開”遞歸調用外,該方法將不再執行任何操作。 如果要避免遞歸調用,我一直在考慮讓循環最多執行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();               
        }             
    }       
  }

當然,您可能需要針對記錄和退出條件進行調整以滿足您的特定需求

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM