转载请注明出处:http://blog.csdn.net/u013258802/article/details/53010157
照着《Android开发艺术探索》一书敲Serializable接口的例子时,遇到 FileNotFoundException
例子很简单就是往文件里存个User对象:
User user = new User(0, "liang", true); ObjectOutputStream out = null; try { out = new ObjectOutputStream(new FileOutputStream("test.txt")); out.writeObject(user); out.close(); } catch (IOException e) { e.printStackTrace(); }
这段抛出异常:FileNotFoundException: Caused by: android.system.ErrnoException: open failed: EROFS (Read-only file system)
看起来感觉像缺少权限,不过跟权限没什么关系。
搜到一篇文章:
高赞回答说:
Please use the version of the FileOutputStream
constructor that takes a File
object. Create that File
object based off of some location that you can write to, such as:
getFilesDir()
(called on yourActivity
or otherContext
)getExternalFilesDir()
(called on yourActivity
or otherContext
)
The latter will require WRITE_EXTERNAL_STORAGE
as a permission.
就是说建议用FileOutputStream()方法使用File对象作参数的构造方法,用一个路径去创建File对象:
File file = new File(mContext.getFilesDir().getPath() + "test.txt");out = new ObjectOutputStream(new FileOutputStream(file));
out = new ObjectOutputStream(new FileOutputStream( mContext.getFilesDir() + "test.txt" ));
获取文件或文件路径的写法很多,Android里的getFilesDir()等方法返回的是File对象,不过File对象可以是文件或路径,这里很明显是路径,所以直接与文件名字符串进行拼接就能得到正确路径,也可采用下面的方式:
File file = new File(mContext.getFilesDir(), "test.txt");当然比较合理的写法是使用getPath()或者对File对象进行检测(isDirectory()):
out = new ObjectOutputStream(new FileOutputStream( mContext.getFilesDir().getPath() + "test.txt" ));out = new ObjectOutputStream(new FileOutputStream( mContext.getExternalFilesDir(null) + "test.txt" ));
getExternalFilesDir(null)也不需要用到WRITE_EXTERNAL_STORAGE
权限。
但在模拟器上有可能提示:
Failed to ensure /sdcard/Android/data/package/files: java.lang.SecurityException: Invalid mkdirs path: /storage/self/primary/Android/data/package/files
因为没有外置存储卡,有时候模拟器设置里明明有设置,那这时候只能建议新建模拟器试试了。
FileInputStream提示 java.io.FileNotFoundException: test.txt: open failed: ENOENT (No such file or directory) 同理。
另外 FileOutputStream 和 FileInputStream 也可以使用 Context.openFileOutput 和 Context.openFileInpu t获取:
out = new ObjectOutputStream(mContext.openFileOutput("test.txt",MODE_PRIVATE));这个方法只能使用文件名作参数,文件存放的位置和 getFilesDir() 相同,都在 /data/data/<package>/files 下。