0
private void SaveLog(boolean externalStorage)
{
    String s = tv_log.getText().toString();
    File file;
    FileOutputStream fos;

    if ( externalStorage )
    {
        try
        {
            file = new File(getExternalFilesDir(null), FILE_LOG);
            fos = new FileOutputStream(file);  // Warning: Resource leak: 'fos' is never closed
        }
        catch(FileNotFoundException e)
        {
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
            return;
        }
    }
    else
    {
        try
        {
            fos = openFileOutput(FILE_LOG, Context.MODE_PRIVATE);
        }
        catch(FileNotFoundException e)
        {
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
            return;
        }
    }


    try
    {
        fos.write(s.getBytes());
        fos.close();
    }
    catch(IOException e)
    {
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        return;
    }
}

行に警告が表示されるのはなぜfos = new FileOutputStream(file)ですか? 興味深いことに、最初のブランチのみを削除if ( externalStorage )して残すと、警告は表示されません。

private void SaveLog(boolean externalStorage)
{
    String s = tv_log.getText().toString();
    File file;
    FileOutputStream fos;

    try
    {
        file = new File(getExternalFilesDir(null), FILE_LOG);
        fos = new FileOutputStream(file);  // OK!
    }
    catch(FileNotFoundException e)
    {
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        return;
    }

    try
    {
        fos.write(s.getBytes());
        fos.close();
    }
    catch(IOException e)
    {
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        return;
    }
}
4

2 に答える 2

1

特定のケースでは、行がグループfos = new FileOutputStream(file);の最後の行の前にあるため、リソースリークの可能性はないと思います。ここに例外がある場合、リソースは作成されません。tryfos

ただし、その行の後にステートメントがある場合、そのステートメントは例外を生成する可能性があり、実行はcatchグループに割り当てられたリソースを解放せずにリターンで終了するグループに移動しtryます。

警告を回避する最も簡単な方法は、 に次を追加することcatchです。

catch(FileNotFoundException e) 
{ 
    try { if(fos != null) fos.close();} catch (Exception e2) {} //Add this line
    Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); 
    return; 
} 

これにより、例外が発生した場合にリソースが解放されることが保証されます。

于 2012-10-16T09:58:50.937 に答える
0

すべての catch ブロックで、 を使用してストリームを閉じますfos.close()

そうしないと、プログラムが try ブロックにヒットし、例外が生成され、ストリームを閉じることなく catch ブロックに移動する可能性があります。これがエラーの原因になっている可能性があります。

于 2012-10-16T10:06:37.647 に答える