为什么 FileOutputStream 会抛出 FileNotFoundException?

Android Developer Reference(本页)说:

Throws FileNotFoundException

但在一开始,它说:

打开与此上下文的应用程序包关联的私有文件以进行写入。如果文件尚不存在,则创建该文件。

如果是这样的话,为什么FileNotFoundException会被抛出呢?

我只是想确保我正确处理所有案件。我正在使用默认功能,所以我是否可以将其包装在一个块中,块中没有任何内容,因为不可能在默认功能中抛出a?try..catchcatchFileNotFoundException

编辑:“默认功能”示例:

String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();

答案 1

例如,如果您尝试打开文件夹,或者您尝试打开的文件不存在,但您也没有创建它的权限,则可能会发生这种情况。


答案 2

ContextImpl.openFileOutput 在 ICS 上实现如下:

@Override
public FileOutputStream openFileOutput(String name, int mode)
    throws FileNotFoundException {
    final boolean append = (mode&MODE_APPEND) != 0;
    File f = makeFilename(getFilesDir(), name);
    try {
        FileOutputStream fos = new FileOutputStream(f, append);
        setFilePermissionsFromMode(f.getPath(), mode, 0);
        return fos;
    } catch (FileNotFoundException e) {
    }

    File parent = f.getParentFile();
    parent.mkdir();
    FileUtils.setPermissions(
        parent.getPath(),
        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
        -1, -1);
    FileOutputStream fos = new FileOutputStream(f, append);
    setFilePermissionsFromMode(f.getPath(), mode, 0);
    return fos;
}

函数 makeFileName 将确保您无法在此处指定任何目录结构:

private File makeFilename(File base, String name) {
        if (name.indexOf(File.separatorChar) < 0) {
            return new File(base, name);
        }
        throw new IllegalArgumentException(
                "File " + name + " contains a path separator");
    }

虽然这似乎不太可能看到 Fnf 异常,但是,您可以看到它不是线程安全的,因此,如果其他线程正在删除 /data/data/com.yourpkg.name/files 目录,f.getParentFile() 仍可能引发该异常。


推荐