Android应用写入内部JSON文件遇EROFS只读文件系统错误的解决办法
解决Android写入JSON文件出现EROFS(只读文件系统)的问题
嘿,这个坑我太熟了!你遇到的open failed: EROFS (Read-only file system)错误,本质原因很简单:你试图写入的JSON文件所在的位置是只读的。
不管是放在项目根目录还是assets目录的文件,最终都会被打包进APK安装包。而Android系统会把APK挂载为只读分区,所以你根本没法直接修改APK里的任何文件——这是系统的安全机制,防止恶意篡改应用资源。
那该怎么解决呢?核心思路是:把只读的原始JSON文件复制到应用拥有写入权限的目录,之后所有读写操作都针对这个复制后的文件。下面给你具体的步骤和代码示例:
第一步:选择合适的可写目录
Android提供了几个安全的可写目录,根据你的需求选:
- 内部存储专属目录:
Context.getFilesDir(),这个目录只有你的应用能访问,不需要任何权限,适合存储敏感数据。 - 外部存储专属目录:
Context.getExternalFilesDir(null),这个目录在外部存储上,卸载应用时会被自动删除,Android 10及以上版本不需要WRITE_EXTERNAL_STORAGE权限,适合存储非敏感的大文件。
第二步:复制原始JSON文件到可写目录
在应用首次启动(或者需要使用JSON文件前),先检查目标目录里有没有该文件,如果没有,就从assets里复制过去。示例代码如下:
private void copyJsonFromAssetsToWritableDir(Context context, String fileName) { File targetFile = new File(context.getFilesDir(), fileName); // 如果目标文件已经存在,就不用重复复制了 if (targetFile.exists()) { return; } try (InputStream inputStream = context.getAssets().open(fileName); OutputStream outputStream = new FileOutputStream(targetFile)) { byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, length); } } catch (IOException e) { e.printStackTrace(); // 这里可以根据需求添加错误处理,比如提示用户 } }
第三步:读写复制后的文件
之后你要读取或写入JSON时,直接操作targetFile(也就是getFilesDir()下的文件)就行。比如写入的示例代码:
private void writeJsonToFile(Context context, String fileName, String jsonContent) { File targetFile = new File(context.getFilesDir(), fileName); try (FileWriter writer = new FileWriter(targetFile)) { writer.write(jsonContent); writer.flush(); } catch (IOException e) { e.printStackTrace(); } }
额外注意事项
- 如果你的应用需要支持Android 9及以下版本,并且使用外部存储目录,记得在
AndroidManifest.xml中添加权限:
同时在运行时请求这个权限(因为是危险权限)。<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - 尽量避免使用外部存储的公共目录(比如
Environment.getExternalStorageDirectory()),Android 10+已经限制了对这些目录的直接访问,而且卸载应用时这些目录里的文件不会被删除,容易留下垃圾。
内容的提问来源于stack exchange,提问作者Madalin Branea
相关产品推荐
相关产品推荐

