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

印刷され、コードが最終的にブロックされ、コードがこれらの2行に表示されます

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

なんで?今回は例外はスローされず、すべて正常に動作します。コードがブロックをキャッチするのはなぜですか? 今回は最終的にコードが正常に戻るはずですか?

ありがとう

4

1 に答える 1

2

メソッドを再帰的に呼び出しています。例外が最初にスローされると、コードはフォークして自分自身を再度呼び出します。実行スレッドがこのメソッドへの 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 に答える