You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

手动删除外部存储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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:48:03