在Android中尝试创建文件:打开失败:EROFS(只读文件系统)

65

这一行:

final FileOutputStream outputStream = new FileOutputStream(name);

结果是FileNotFoundException,错误消息为/2ozjfFQzwv: open failed: EROFS (Read-only file system),其中"2ozjfFQzwv"是我作为文件名传递的参数。

我已经尝试过具有和不具有WRITE_INTERNAL_STORAGE权限的情况。如何创建这个可写文件?

或者,我只想能够将图像传递给新活动,并且它太大了,无法在额外操作中进行序列化。是否有比先将其写入文件然后再次读取更简单的方法?所有问题似乎都是关于写入SD卡的,但我不想这样做,因为很多人没有SD卡插槽。

8个回答

97
我已经尝试了有和没有WRITE_INTERNAL_STORAGE权限。
在Android中没有WRITE_INTERNAL_STORAGE权限。
如果您的应用程序没有超级用户权限,则无法在内部存储的根目录下写入文件。您可以使用带有File对象参数的FileOutputStream构造函数。请根据需要写入的位置创建该File对象,例如:
- getFilesDir() (在Activity或其他Context上调用) - getExternalFilesDir() (在Activity或其他Context上调用)
后者将需要WRITE_EXTERNAL_STORAGE权限。
您可以将数据暂时放在静态数据成员中,不必先将其写入文件再读取。
“SD卡槽”并不重要。99%的Android设备用户都会有外部存储 - 除非用户在4年以上的老设备上移除了他们的SD卡。自2010年中期以来制造的设备具有内置闪存作为外部存储,而不是作为可移动介质。

5
+1表示赞同使用getFilesDir()方法,谢谢。 new BufferedWriter(new FileWriter(getFilesDir() + FILENAME)); 可以翻译为“创建一个新的BufferedWriter对象,并将其与通过getFilesDir()方法获取的文件路径和FILENAME变量所代表的文件名拼接后的完整路径相关联”。 - Owen B
旧设备?就我使用 Nexus 7 2013 的经验而言,它不支持 SD 卡... Nexus 10 也是如此,可能还有其他的 Nexus 设备。 - PawelP
12
所有Nexus系列设备都有外部存储,但它们没有可移动存储。外部存储并不意味着可移动存储。 - CommonsWare
你说得没错,我应该仔细阅读你的帖子并三思而后行。 - PawelP
对于来自未来的其他访问者,文档中提供的解释是getExternalFilesDir将优先考虑可移动存储,但是在API 21+中,Environment.isExternalStorageEmulated(File)可以确定它是否仅是单独内部分区的挂载点。 - Abandoned Cart

17

尝试使用WRITE_EXTERNAL_STORAGE权限,无论是否存在外部卡都应该使用。

以下方法对我很有效:

path = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_MOVIES);
File file = new File(path, "/" + fname);

并将我的文件放在适当的文件夹中


2
从API级别19开始,在使用getExternalFilesDir(String)和getExternalCacheDir()返回的应用程序专用目录中读写文件时,不再需要此权限。https://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE - androidguy

8
这是来自安卓开发者的简单示例。
基本上,您可以像这样在内部存储中编写文件:
String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();

6

添加

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

在清单文件中并使用与马丁相同的内容:

path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES); 
File file = new File(path, "/" + fname);

它运行成功了。


3
如果你的应用程序使用WRITE_EXTERNAL_STORAGE权限,那么它隐含地也具有读取外部存储的权限。 - IliaEremin
@ilyaEremin - 确实如此 - Martin

3

正如其他人所提到的那样,Android上的应用程序无法将文件写入内部存储器中除了它们自己的私有存储空间之外的任何文件夹(该文件夹位于/data/data/PACKAGE_NAME下)。

您应该使用API获取允许您的应用程序使用的正确路径。

阅读this


1

如果要使用应用程序的内部存储,您不需要权限,但您可能需要使用:File directory = getApplication().getCacheDir();来获取应用程序允许的目录。

或者:
getCashDir(); <-- 应该可以工作
context.getCashDir();(如果在广播接收器中)
getDataDir(); <-- Api 24


1
如果在单元测试或仪表测试中遇到此问题,请确保在应用程序上下文中调用getFilesDir(),而不是测试上下文。即使用以下代码:
Context appContext = getInstrumentation().getTargetContext().getApplicationContext();

不要。
Context appContext = InstrumentationRegistry.getContext;

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接