2011-07-21 8 views
0

私のプログラムでファイルを消去する必要があります。ここエラーを回避しながらファイルを開いたり、書き込みしたり、保存したりするにはどうすればよいですか?

public static void erase(String string) { 
    FileWriter fw = null; 
    try { 
     fw = new FileWriter(string); 
     fw.write(new String()); 
    } catch (IOException ie) { 
     e.printStackTrace(); 
    } finally { 
     fw.flush(); 
     fw.close(); 
    } 
} 

いくつかの問題:

  • fwが正しくファイルが欠落し、何らかの理由(初期設定していない場合は、無効persmissions私のソリューションはそうのようなことをするだろうerase()方法を持っていることでした、など)、ブロックfinallyでブロックしようとすると、NullPointerExceptionが発生します。

  • finallyブロックがない場合は、上記の理由でNullPointerExceptionがスローされている可能性があります。

  • ファイルをtryブロック内で閉じると、ファイルが正しく開かれてもリソースがリークする可能性がありますが、正しく書き込まれません。

他にどのような問題がありますか、どのようにこの方法を強化できますか?

+0

RandomAccessFile.setLength(0)は読みやすくなる可能性があります(文字エンコーディングにBOM文字または2文字が含まれる可能性があります)。 –

答えて

3

あなただけのif文で、最終的な機能をラップすることができます。これは、ファイルがこれまでに開かれた場合、それはクローズされるようになります

if(fw != null){ 
    fw.close(); 
} 

。それが最初に開かれなかったなら、それは何もしません。それはあなたが望むものです。

また、ポスティングのようなものかどうかはわかりませんが、一般的にはcatchtブロックでスタックトレースを出力して(例外を「飲み込む」)続けることはお勧めできません。例外がスローされるようにする必要があります。これはバグを隠して、それらを非常に難しくする可能性があるからです。

編集:下記のコメントを参照してください。

+2

ええ、みんな、すでに声明の中で起こっています。その直前にそれを実行する必要はありません。 –

+0

@owlstead:一般的に、暗黙のフラッシュで、close();でIOExceptionが発生する可能性があります。むしろ 'try'ブロックに明示的にフラッシュを置きます。つまり、実際には近くで実際に例外をスローするのは本当に特別なことです。 –

1

メインブロックにflush()を含めて、キャッチ内にclose()のみを含めます。そして、閉じる前にnullをチェック:

finally { 
    if(fw!=null) { fw.close(); } 
    } 

をメインブロックでフラッシュを使用すると、またcloseをキャッチし、エラーを記録したり、無視/試すことができます。

finally { 
    if(fw!=null) { 
     try { fw.close(); } catch(Throwable thr) { log.printError("Close failed: "+thr); thr.printStackTrace(); } 
     } 
    } 

または(一般的にはお勧めしません) :

finally { 
    try { fw.close(); } catch(Throwable thr) {;} 
    } 

EDIT

I/Oを処理するための最高一般的なJavaのイディオムは、IMO、次のとおりです。

FileWriter fw=null; 
try { 
    fw=new FileWriter(string); 
    fw.write(new String()); 
    fw.close(); 
    fw=null; 
    } 
catch(IOException ie) { 
    // do something real here to handle the exception, or don't catch it at all. 
    } 
finally { 
    if(fw!=null) { 
     try { fw.close(); } catch(Throwable thr) { thr.printStackTrace(); } // now we're really out of options 
     } 
    }  

これはcatchclose()自体によってスローされた例外をキャッチして対処することを可能にする重要な効果を持っています。(あなたが何らかの方法で例外を処理できるかどうcatch句は唯一の存在であるべきである。ませキャッチをし、無視し、あなたは、単にキャッチし、トレースするべきではありません一般

+0

finallyブロック(Throwable)で 'Throwable'をキャッチすることは、潜在的な重大な問題を隠すため、賢明ではないようです。 NPEを捕まえることは意味をなさないだろう...しかし、単純にヌルをチェックできるときは、それは過剰と思われる。 – dhg

+0

@dhg:まさに、私の最初の提案と同じです。 IOExceptionを内部的に処理する場合は 'close()'の結果として 'throws IOException'を残します。あなたは自分自身に "* flushが既に行われている場合、closeが失敗するとエラーを記録する以外に何ができるのですか"と尋ねなければなりません。 –

1

最高に

FileWriter fw = new FileWriter(string); 
try { 
    fw.write(new String()); 
    fw.flush(); 
} catch (IOException ie) { 
    ie.printStackTrace(); 
} finally { 
    fw.close(); 
} 

説明:

    私の知る限りでは、これはあなたのコードを書くための正しい慣用的な方法であります
  • new FileWriter()が例外をスローすると、何もクリーンアップする必要はありません。このメソッドはfinallyを実行せずに終了します。
  • finallyではなくtryfw.flush()を記載してください。 2つの理由があります:書き込みが失敗した場合、フラッシュを邪魔する必要はありません。また、にflush()を入れて例外をスローすると、close()はスキップされます。
+1

コメント:1. 'new String()'は '' "と同じです。 2. 'close()'は自動的に 'flush()'を意味します。 3.ファイルを削除したい場合、 'new File(filepath).delete()'はどうですか? 4.ファイルをゼロバイトにしたい場合、 'new FileOutputStream(filepath).close()'はどうでしょうか? – Nayuki

+0

これは、ほとんどのWriterコンストラクタからスローされたIOExceptionを捕捉できません。 –

+0

良い点。私の悪い。 – Nayuki

関連する問題