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

Android写入文本文件始终失败,求助解决FileNotFound异常

解决Android写入外部存储/公共目录时的FileNotFound异常

嘿,我之前也踩过几乎一模一样的坑!这种FileNotFoundException在操作外部存储时真的太常见了,咱们一步步拆解问题,找到解决方案:

1. 先搞定权限问题(最常见的诱因)

Android 6.0(API 23)之后,WRITE_EXTERNAL_STORAGE属于危险权限,光在AndroidManifest.xml里声明还不够,必须在运行时动态申请:

<!-- 先在Manifest中声明基础权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Android 10+ 若要绕过Scoped Storage限制,需额外声明(但Google审核严格,非必要不推荐) -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

然后在代码里动态发起权限申请:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
            1001);
}

注意:Android 11(API 30)之后,WRITE_EXTERNAL_STORAGE权限已经被弱化,就算申请成功,也无法直接用File类操作公共目录,得用下面说的Scoped Storage方案。

2. 确保目录/文件存在再写入

你拿到的路径比如storage/emulated/0/DCIM,虽然DCIM目录一般由系统创建,但特殊场景下可能不存在。写入前一定要先判断并创建目录:

File dcimDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
// 用mkdirs()递归创建所有父目录,mkdir()只能创建单级目录
if (!dcimDir.exists() && !dcimDir.mkdirs()) {
    Log.e("StorageError", "无法创建DCIM目录");
    return;
}
// 创建目标文件对象
File targetFile = new File(dcimDir, "my_content.txt");
// 接下来执行写入操作

3. Android 10+ 必须适配Scoped Storage

从Android 10(API 29)开始,系统默认启用Scoped Storage,直接用File类操作公共存储目录会被限制。这时候推荐用MediaStore来写入文件,比如写入文本到DCIM目录的示例:

ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, "my_content.txt");
values.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain");
// 指定文件存放的相对路径
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);

// 获取外部存储的Content Uri
Uri uri = getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);
if (uri != null) {
    try (OutputStream outputStream = getContentResolver().openOutputStream(uri)) {
        // 写入文本内容
        String content = "这是要写入的文本内容";
        outputStream.write(content.getBytes(StandardCharsets.UTF_8));
        Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(this, "写入失败", Toast.LENGTH_SHORT).show();
    }
}

4. 绝对别硬编码路径!

你提到的"/sdca..."明显是拼写错误,而且就算写对"/sdcard/"也不推荐——不同设备的外部存储路径可能存在差异,一定要用系统提供的API获取路径,比如:

  • 废弃但仍可参考的:Environment.getExternalStorageDirectory().getAbsolutePath()
  • 公共目录API:Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)(Android 10+推荐用MediaStore替代)

总结一下排查顺序:先确认权限是否申请成功→检查目录是否存在并创建→Android 10+改用MediaStore API→避免硬编码路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:46:55