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

安卓文件写入异常:文件存在却触发FileNotFoundException

安卓FileNotFoundException排查:文件存在却无法写入

日志信息

D/sticky note: /storage/emulated/0/Pictures/PlantImages/20230325_151658.jpg文件已存在!
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Pictures/PlantImages/20230325_151658.jpg

出错的写入代码

Uri uri = AddActivity.uri1;
String path = getFile(uri);

File file = new File(path);
file.setWritable(true);
//MeViewHolder
//MeViewHolder
if (!file.exists()) { System.out.println("file does not exist"); return; }
// 打开可写通道
try (FileOutputStream outputStream = new FileOutputStream(file)) {
   // 写入数据
   byte[] data = "Hello, World!".getBytes();
     outputStream.write(data);
   System.out.println("write success"); }
     catch (IOException e) { e.printStackTrace(); }

已确认的情况

  • 文件实际存在,路径完全正确,已获取读写权限
  • 该图片文件可通过OpenCV正常处理
  • 图片上传相关代码片段:
Bitmap img = (Bitmap) data.getExtras().get("data");
imgCamera.setImageBitmap(img);

图片保存到MediaStore的代码

// 将图片保存至设备MediaStore
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File folder = new File(Environment.getExternalStorageDirectory(), FOLDER_NAME);
if (!folder.exists()) {
    folder.mkdirs();
}
String fileName = timeStamp + ".jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/" + FOLDER_NAME);
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
try {
    OutputStream outputStream = getContentResolver().openOutputStream(uri);
    if (outputStream != null) {
        // 压缩图片并保存至输出流
        img.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
        outputStream.close();
        Toast.makeText(this, "图片保存成功", Toast.LENGTH_SHORT).show();
        AddActivity.uri1 = uri;
    }
} catch (IOException e) {
    e.printStackTrace();
}

可能的异常原因及排查点

  1. Android 10+分区存储限制
    从Android 10开始启用分区存储,直接通过File API访问外部媒体文件会有权限限制。你保存图片时用MediaStore获取Uri,但写入时转成File路径操作,这是核心冲突。应该直接用ContentResolver.openOutputStream(uri)写入,而非FileOutputStream。

  2. 权限未正确生效
    Android 13+针对媒体文件新增READ_MEDIA_IMAGES/WRITE_MEDIA_IMAGES权限,若targetSdkVersion >=33,需申请这些权限而非旧的WRITE_EXTERNAL_STORAGE。可通过Context.checkSelfPermission()再次验证权限状态。

  3. Uri转路径错误
    getFile(uri)方法可能返回无效路径,比如MediaStore的Uri对应的真实物理路径和你拿到的不一致,或者该路径只是媒体库的映射,并非可直接写入的路径。

  4. 文件被占用
    图片若被其他应用或系统进程占用(如图库加载),会导致无法写入。可重启设备测试,或确认无其他进程在使用该文件。

内容的提问来源于stack exchange,提问作者Zhu Pengming

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 17:12:40