在我的真实项目中重现问题的简短方法。环境:Android SDK 1.16,Eclipse 4.2.0,Windows。创建默认的Android应用程序并将以下代码添加到MainActivity.java:
private void Save1(boolean externalStorage)
{
String s = "12345";
File file;
FileOutputStream fos = null;
if ( externalStorage )
{
try
{
file = new File(getExternalFilesDir(null), "log");
fos = new FileOutputStream(file); // Resource leak: 'fos' is never closed
}
catch(FileNotFoundException e)
{
return;
}
}
else
{
try
{
fos = openFileOutput("log", Context.MODE_PRIVATE);
}
catch(FileNotFoundException e)
{
return;
}
}
try
{
fos.write(s.getBytes());
fos.close();
}
catch(IOException e)
{
return;
}
}
private void Save2(boolean externalStorage)
{
String s = "12345";
File file;
FileOutputStream fos = null;
try
{
file = new File(getExternalFilesDir(null), "log");
fos = new FileOutputStream(file); // OK
}
catch(FileNotFoundException e)
{
return;
}
try
{
fos.write(s.getBytes());
fos.close();
}
catch(IOException e)
{
return;
}
}
在fos = new FileOutputStream(file)
函数中行Save1
,警告:Resource leak: 'fos' is never closed
Save2
函数中的同一行:没有警告。
请不要发送未经测试的答案,问题并不像看起来那么简单。将fos.close()
添加到函数的不同部分并不会有帮助。
答案 0 :(得分:2)
如果我在if块中添加了一个finally块,就像这样:
if (externalStorage) {
try {
fos = new FileOutputStream(new File(getExternalFilesDir(null),
"log"));
} catch (FileNotFoundException e) {
return;
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
try {
fos = openFileOutput("log", Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
return;
}
}
这很有趣......
所以我的猜测是,所以如果你在try块中打开一个Stream并且catch块有一个return语句,那么应该有一个关闭流的finally块。
像这样......
在eclipse中的一个简单的java项目中尝试了相同的代码并且仍然收到了警告。所以它看起来与lint或android无关。它看起来像是eclipse编译器问题。以下是代码,我不得不创建一个虚拟的openFileOutput()方法,因为它不可用于java:
private void Save1(boolean externalStorage) {
String s = "12345";
FileOutputStream fos = null;
if (externalStorage) {
try {
fos = new FileOutputStream(new File("c://", "log"));
} catch (FileNotFoundException e) {
return;
}
} else {
try {
fos = openFileOutput("log", -1);
} catch (FileNotFoundException e) {
return;
}
}
try {
fos.write(s.getBytes());
fos.close();
} catch (IOException e) {
return;
}
}
/**
* @param string
* @param i
* @return
*/
private FileOutputStream openFileOutput(String string, int i)
throws FileNotFoundException {
return null;
}
答案 1 :(得分:1)
这不是一个答案,但为了清楚OP和其他读者而不是评论,这里添加了。
我使用当前版本的平台工具链(2012年10月14日修订版)在IDEA 11.2 API 15中对此进行了测试,并且没有lint警告,编译错误或运行时错误。我通过创建异常并将useExternalStorage设置为true和false来强制该方法遍历每个路径。
我猜这是你的工具链中的lint / compile错误,或者可能是Eclipse(尽管不太可能,Eclipse本身是否会像这样进行任何检查?)。
[编辑]
只是一个想法,(我会测试但我忘记了如何使用Eclipse)但是FileInputStream(文件)可能会抛出一个SecurityException,它将被抛出到你的调用堆栈中的某个地方。如果你抓住它会发生什么?
[编辑]
这是我得到的最接近的警告,并没有任何相关性。我确信警告不是由你决定的。
答案 2 :(得分:0)
如果Exception
,fos
将无法关闭。将finally
添加到try-catch
可以解决此问题。
try
{
fos = openFileOutput("log", Context.MODE_PRIVATE);
}
catch(FileNotFoundException e)
{
return;
}
//add this:
finally {
if (fos != null) {
fos.close();
}
}