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

7gcisfzg  于 2023-08-01  发布在  Android
关注(0)|答案(3)|浏览(101)

要在Android中从应用的私有存储区域读取文件,请使用函数openFileInput()
我的问题是,有没有办法在调用这个函数之前检查这个文件是否存在?这个函数可以抛出一个FileNotFoundException,但是我觉得调用这个函数然后基于一个try-catch做一些事情是一个不好的做法。
使用File.exist()似乎是一件奇怪的事情,因为它需要示例化一个类,我不确定是否只是将文件的名称传递给它会让它在我的手机的私人区域找到文件。

nbnkbykc

nbnkbykc1#

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;

mklgxw1f

mklgxw1f2#

该函数可以通过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。在这种情况下,即使new FileInputStream可能已经成功,您也会打印错误消息。这种竞争条件可能是无害的。)
另一个问题是FileInputStream被声明为抛出IOException。检查文件是否存在的测试只处理一种可能的故障模式。您的代码无论如何都必须处理其他IOException
@碎片评论道:
例外应该是当你无法控制的事情实际上出错时。在这种情况下,我可以完全控制它。
实际上,你并不能完全控制它。当然不是在一般情况下。即使在您的特定用例中,竞争条件在理论上仍然是可能的。
但这种思路的真实的问题是,在异常/异常处理是最好的解决方案的情况下,你最终会跳过障碍来避免异常。这使得代码更复杂,可读性更差,并且可能更慢和/或更脆弱。
正常的教条是这样的:

  • “例外情况只应在例外情况下使用”*。

这和你说的不一样。“例外”这个词实际上只是“不正常”的意思。这比“有些事情实际上出了问题,你无法控制”有更广泛的含义。
我倾向于对教条进行如下扩展:

  • 异常 * 不应该 * 用于正常流控制。
  • 异常 * 不应该 * 被使用,如果他们要证明太昂贵 * 平均 *。
  • 如果你用来避免异常的测试不可靠,那么就应该使用异常。
  • 如果你用来避免异常的测试平均来说太昂贵,那么就应该使用异常。
  • 如果异常能显著简化你的代码,那么就应该使用异常(对上面的代码取模)。简单性的标准是代码是否可被普通Java程序员阅读。

(Note- “平均”和“太贵”...而“正常”是主观的。)
现在,人们可以一直争论一个事件需要有多特殊,但我的看法是,这实际上是一个平衡方法相对简单性(在上下文中)与平均性能成本(在上下文中)的问题。任何不考虑权衡和背景的教条式规则在某些情况下都会对你造成伤害。

t40tm48m

t40tm48m3#

这对我来说很有用。

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

字符串
但是有时候它会返回一个异常与亚行合作。

相关问题