手动删除外部存储MP3后重建报FileNotFoundException(EEXIST)错误问询
java.io.FileNotFoundException: /storage/emulated/0/Ringtones/sound1.mp3: open failed: EEXIST (File exists)
上述报错是Android平台特有的媒体存储索引与物理文件不同步导致的问题,根源是手动删除物理文件后,系统媒体库没有及时更新对应记录,创建同名文件时系统校验媒体库索引发现重名就会抛出存在错误,哪怕物理文件已经不存在。
可行解决思路
- 方案1:创建目标文件前,先触发单路径的媒体库扫描,清除无效索引后再执行创建逻辑
调用MediaScannerConnection扫描要创建的文件路径,等扫描回调完成后再操作文件,示例代码:String targetPath = "/storage/emulated/0/Ringtones/sound1.mp3"; MediaScannerConnection.scanFile(context, new String[]{targetPath}, null, (path, uri) -> { // 扫描完成后再执行文件创建、OutputStream初始化操作 File mp3File = new File(path); // 后续写入逻辑 }); - 方案2:针对Android 10(API 29)及以上系统,改用MediaStore API操作音频文件
分区存储规则下直接使用File API访问公共目录的方式已不被官方推荐,通过MediaStore插入、删除文件会自动同步媒体库索引,从根源避免索引和物理文件不一致的问题。 - 方案3:保留File API的前提下,创建文件前先清理媒体库中的无效记录
先调用ContentResolver删除媒体库中对应路径的记录,再执行文件创建逻辑,示例代码:String targetPath = "/storage/emulated/0/Ringtones/sound1.mp3"; // 清理媒体库无效记录 getContentResolver().delete( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MediaStore.Audio.Media.DATA + " = ?", new String[]{targetPath} ); // 再初始化FileOutputStream创建文件 - 方案4(仅低版本测试用):发送全局媒体扫描广播
Android 7.0以下版本可以发送全局媒体挂载广播触发全量扫描,高版本系统对该广播有权限限制,不推荐线上使用:sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
内容的提问来源于stack exchange,提问作者Migas11
相关产品推荐
相关产品推荐

