Android Kotlin开发如何向已存在的文本文件追加写入内容?
Android SAF框架下文件追加写入实现方案
你当前使用的是Android系统提供的存储访问框架(SAF)实现文件保存,追加写入的逻辑不需要额外加复杂的文件存在校验,核心修改点在打开输出流的位置。
具体修改步骤
- 追加模式的开关在
contentResolver.openOutputStream()方法的参数里:你当前调用的单参数版本默认是覆盖写模式,只要传入第二个模式参数*"wa"*,就可以自动适配两种场景:- 目标文件已存在:直接在文件末尾追加新内容,不会覆盖原有数据
- 目标文件是新建文件:自动创建空文件后写入内容,不会抛出异常
- 逻辑插入位置就在你当前
saveLauncher回调里拿到Uri之后、打开输出流的那一行,不需要改动其他文件选择逻辑。 - 不需要自己单独实现文件存在校验逻辑:系统在打开输出流的时候会自动处理文件状态,如果你有业务场景需要提前判断文件是否存在,可以通过
ContentResolver查询对应Uri的文档信息判断。
修改后的核心代码
private var saveLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { val uri = result.data?.data try { // 第二个参数传"wa"即开启写入+追加模式 val outputStream = uri?.let { contentResolver.openOutputStream(it, "wa") } // 追加前先写入换行符,避免新内容和旧内容拼接在同一行 val contentToWrite = "\n${getMeasurement()}" outputStream?.write(contentToWrite.toByteArray()) outputStream?.flush() outputStream?.close() Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show() } catch (e: Exception) { Toast.makeText(this, "保存失败:${e.localizedMessage}", Toast.LENGTH_SHORT).show() } } }
可选:手动校验文件是否存在的实现
如果业务逻辑需要提前确认目标文件是否存在,可以直接用以下方法查询,不需要申请额外权限:
private fun isTargetFileExists(uri: Uri): Boolean { val cursor = contentResolver.query(uri, arrayOf(DocumentsContract.Document.COLUMN_DOCUMENT_ID), null, null, null) val fileExists = cursor?.use { it.count > 0 } ?: false return fileExists }
额外提示
ACTION_CREATE_DOCUMENT每次启动都会弹出系统文件选择器,适合首次选文件的场景,如果需要多次往同一个文件追加内容,可以把第一次拿到的Uri做持久化存储,后续直接用这个Uri打开输出流即可,不需要每次弹选择器。- 如果需要应用重启后依然能访问之前选中的文件,拿到Uri后要调用
takePersistableUriPermission方法获取持久化访问权限,否则重启后Uri会失效。
内容的提问来源于stack exchange,提问作者Jukka Koivu
相关产品推荐
相关产品推荐

