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

Jetpack Compose中通过文件选择框打开文本文件并逐行读取报错问题

问题分析与解决方案

错误原因

你通过ActivityResultContracts.OpenDocument()获取的Uri是内容URI,并非直接的文件系统路径。uri.path中的/document/document:1000014685是Android内容提供者的文档标识格式,其中1000014685是该文档在内容提供者中的唯一ID,不是真实的文件路径,因此直接用File(uri.path)会触发文件找不到的异常。

正确实现方式

要读取内容URI指向的文件,必须通过ContentResolver打开输入流,而非直接操作文件路径。修改后的Loadfile函数如下:

@Composable
fun Loadfile(uri: Uri?) {
    val context = LocalContext.current

    Log.d("Loadfile", "Load ${uri.toString()}")

    if (uri == null) {
        Log.e("Loadfile", "File could not load!")
    } else {
        try {
            context.contentResolver.openInputStream(uri)?.use { inputStream ->
                BufferedReader(InputStreamReader(inputStream)).use { br ->
                    // 逐行读取内容
                    var line: String?
                    var totalLines = 0
                    while (br.readLine().also { line = it } != null) {
                        totalLines++
                        Log.d("Loadfile", "Line $totalLines: $line")
                    }
                    Log.d("Loadfile", "Total Lines: $totalLines")
                }
            } ?: run {
                Log.e("Loadfile", "Failed to open input stream for URI")
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
}

关键说明

  • ContentResolver.openInputStream(uri):这是访问系统文件选择器返回文档的标准方式,通过内容URI获取文件的输入流。
  • 借助use函数自动管理流的关闭,避免资源泄漏。
  • 无需额外申请READ_EXTERNAL_STORAGE权限:OpenDocument()通过系统文件选择器获取了临时访问权限,系统已授权应用访问该文档。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:03:31