在ICS上,ContextImpl.openFileOutput的实现如下:
@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()仍可能抛出该异常。