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

要从应用程序的私有存储区域读取Android中的文件,请使用函数openFileInput()

我的问题是,是否有一种方法来检查此文件是否存在之前调用此函数? 该函数可以抛出一个FileNotFoundException ,但我觉得这样调用,然后做一些基于trycatch是不好的做法。

使用File.exist()似乎也是一个奇怪的事情使用也因为它需要实例化一个类,我不知道是否只是传递文件的名称,它会让它find我的手机的私人区域中的文件。

Solutions Collecting From Web of "在调用openFileInput之前检查文件是否存在"

 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; 

该函数可以通过一个FileNotFoundException,但我觉得这样调用,然后做一些基于尝试catch是不好的做法。

我不同意。 国际海事组织,这是testing,如果该文件存在之前打开这是不好的做法。 比较这两个版本的代码:

 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 。 如果有问题的文件是安全关键的,那么这种竞争条件可以被利用来破坏安全。 (实际上,还有第二种竞争条件,文件正在被创build,而file.exists()在随后的打开成功的时候返回false,但是这种竞争条件可能是无害的)。

另一个问题是FileInputStream被声明为抛出IOException 。 testing文件是否存在只处理可能的失败模式之一。 无论如何,你的代码将不得不赶上和处理其他IOException


@Pieces评论道:

例外情况应该是当某些事情出现错误时,你无法控制。 在这种情况下,我完全可以控制它。

其实,你没有完全的控制权。 当然不是在一般情况下。 即使在你的具体使用情况下,理论上的竞争条件仍然是可能的。

但是,这个思路的真正问题是,你最终需要跳槽,以避免在例外/exception处理是最好的解决scheme的情况下出现exception。 这使代码更复杂,可读性更差,并且可能更慢和/或更脆弱。

正常的教条是这样的:

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

这跟你说的话不一样。 “例外”一词的意思是“不正常”。 这比“你无法控制的事实上出了问题”有更广泛的意义。

我倾向于扩展的教条如下:

  • 例外情况不应该用于正常stream量控制。

  • 例外情况不应该被使用,如果他们平均要certificate太贵。

  • 如果您用来避免这些testing的testing不可靠, 应该使用例外。

  • 如果您用来避免这些testing的testing平均成本过高,则应该使用例外。

  • 如果它们显着简化了你的代码,就应该使用exception(以上面的模为例)。 简单的标准是代码是否可以被普通的Java程序员读取。

(注 – “平均”和“太贵”…)

现在人们可以争辩说,直到奶牛回家才知道事件需要多么特殊 ,但我认为这实际上是一个平衡方法的相对简单性(在上下文中)与平均性能成本(在上下文)。 任何不考虑权衡和背景的教条规则在某些情况下会对你造成伤害。

这为我工作。

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

但发生,有些时候,它会返回一个exception…与adb一起工作。