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
相关产品推荐
相关产品推荐

