在调用openFileInput之前检查文件是否存在

时间:2012-01-15 03:28:37

标签: java android file file-exists

要从应用的私人存储区域读取Android中的文件,请使用功能openFileInput()

我的问题是,有没有办法在调用此函数之前检查此文件是否存在?该函数可以抛出一个FileNotFoundException,但我觉得要调用它然后根据try - catch做一些事情是不好的做法。

使用File.exist()似乎也很奇怪,因为它需要实例化一个类,我不确定是否只是将文件名传递给它会让它在私有区找到文件我的手机。

3 个答案:

答案 0 :(得分:46)

public boolean fileExists(Context context, String filename) {    
    File file = context.getFileStreamPath(filename);
    if(file == null || !file.exists()) {
        return false;
    }
    return true;
}

编辑:

此外,这是外部存储中文件的另一种方式。

String fileUrl = "/appname/data.xml";
String file = android.os.Environment.getExternalStorageDirectory().getPath() + fileUrl;
File f = new File(file);

if(f.exists())
return;

答案 1 :(得分:30)

  

该函数可以通过FileNotFoundException,但我觉得调用它然后基于try catch做一些事情是不好的做法。

我不同意。 IMO,它正在测试文件是否存在,然后打开这是不好的做法。比较这两个版本的代码:

File f = new File("someFile");
InputStream is;

版本#1

if (f.exists()) {
    is = new FileInputStream(f);
    ...
} else {
    System.err.println("Doesn't exist");
}

版本#2

try {
    is = new FileInputStream(f);
    ...
} catch (FileNotFoundException ex) {
    System.err.println("Doesn't exist");
}

第一个版本存在许多问题:

  • 当您致电f.exists()时,版本#1会进行额外的系统调用。这使得第一个版本平均较慢,除非文件赢得的概率很高。

  • 版本#1有竞争条件。如果某个外部进程几乎同时删除了该文件,则最终可能会返回file.exists()为true,然后FileInputStream构造函数会抛出FileNotFoundException。如果有问题的文件是安全关键的,那么这种竞争条件可被利用来破坏安全性。 (实际上,还有第二种竞争条件,正在创建文件,file.exists()在后​​续尝试打开它时会返回false。但是这种竞争条件可能是无害的。)

另一个问题是FileInputStream被声明为抛出IOException。测试以查看文件是否存在仅处理可能的故障模式之一。无论如何,你的代码必须捕获并处理其他IOException


@Pieces评论道:

  

例外应该是当你无法控制的事情出现问题时。在这种情况下,我完全控制它。

实际上,您无法完全控制它。当然不是一般情况。即使在您的特定用例中,理论上仍然可能存在竞争条件。

但是,这种思路的真正问题在于,在异常/异常处理是最佳解决方案的情况下,您最终会跳过箍以避免异常。这使得代码更复杂,可读性更低,而且可能更慢和/或更脆弱。

正常的教条是这样的:

  

"例外情况只能在特殊情况下使用"

这跟说你说的不一样。这个词"特殊"真的只是意味着"不正常"。这比#34更广泛的含义;实际上你无法控制的事情是错误的。

我倾向于扩展教条如下:

  • 例外不应用于正常的流量控制。

  • 如果平均

  • 如果用于避免它们的测试不可靠,则应使用

  • 如果您用来避免它们的测试平均

    ,则
  • 如果显着简化您的代码(以上为模),则应使用。简单的标准是普通Java程序员是否可以读取代码。

(注意 - "平均而且#34;" 昂贵" ......)

现在有人可以争论,直到奶牛回家了事件需要多少,但我的看法是,这实际上是平衡方法的相对简单性(在上下文中) )与平均绩效成本(在上下文中)。在某些情况下,任何没有考虑到权衡和背景的教条规则都会对你造成伤害。

答案 2 :(得分:0)

这项工作适合我。

try {
  FileInputStream fis = openFileInput(String filename);
  // ... do something
try {
    fis.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
} catch (FileNotFoundException e) { 
  e.printStackTrace();
}

但有些时候,它会返回一个异常...使用adb。