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

Android 10及以上版本如何通过MediaStore编辑文件而非新建?

如何通过MediaStore编辑外部Documents目录下的已有文件?

这问题我之前也踩过坑!你用insert()方法的话,MediaStore的逻辑就是每次都创建新的文件条目,哪怕文件名重复,系统也会自动给新文件加后缀(比如doc (1).txt),所以要编辑原文件的核心是先找到已存在文件的URI,而不是直接插入新条目。

解决思路

  1. 先通过ContentResolver查询Documents目录下是否存在目标文件
  2. 如果查询到已存在的URI,就直接打开输出流编辑它;如果没查到,再用原来的insert()方法创建新文件

修改后的完整代码

val resolver = applicationContext.contentResolver
val fileName = "doc.txt"
val relativePath = "Documents"
val mimeType = "text/plain"

// 1. 查询已存在的文件URI
var existingUri: Uri? = null
val projection = arrayOf(MediaStore.Files.FileColumns._ID)
val selection = "${MediaStore.MediaColumns.DISPLAY_NAME} = ? AND ${MediaStore.MediaColumns.RELATIVE_PATH} = ?"
val selectionArgs = arrayOf(fileName, "$relativePath/") // RELATIVE_PATH存储时结尾带斜杠,查询要匹配

resolver.query(
    MediaStore.Files.getContentUri("external"),
    projection,
    selection,
    selectionArgs,
    null
)?.use { cursor ->
    if (cursor.moveToFirst()) {
        val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID))
        existingUri = MediaStore.Files.getContentUri("external").buildUpon()
            .appendPath(id.toString())
            .build()
    }
}

// 2. 处理编辑或创建逻辑
val targetUri = existingUri ?: run {
    val contentValues = ContentValues().apply {
        put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
        put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
        put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath)
    }
    resolver.insert(MediaStore.Files.getContentUri("external"), contentValues)
}

targetUri?.let { uri ->
    // 打开输出流:"w"覆盖原内容,"wa"追加内容
    resolver.openOutputStream(uri, "w")?.use { outputStream ->
        outputStream.write("new line1".toByteArray(Charset.defaultCharset()))
        outputStream.write("new line2".toByteArray(Charset.defaultCharset()))
        // use{}会自动关闭流,无需手动调用close()
    }
}

关键细节说明

  • 查询RELATIVE_PATH时,条件里的路径必须以斜杠结尾(比如"Documents/"),因为MediaStore存储的该字段自带结尾斜杠
  • 打开输出流的第二个参数控制写入模式:"w"会清空原文件内容再写入,"wa"会在原内容末尾追加
  • 用Kotlin的use{}包裹流操作,能自动处理资源释放,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 22:12:45