Android读取手机本地文本文件时报open failed: ENOENT错误怎么办
ENOENT错误排查与解决方案
1. 存储权限校验
- Android 6.0(API 23)及以上版本,仅在
AndroidManifest.xml声明读取权限不生效,必须在运行时向用户动态申请READ_EXTERNAL_STORAGE权限 - Android 13(API 33)及以上版本,读取公共目录非媒体类文件,不再支持通过原始路径直接访问,也不能通过普通存储权限授权访问,必须使用存储访问框架(SAF)或者MediaStore获取文件访问权限
2. 路径合法性校验
- 如果你拿到的
txt_file是content://开头的Uri字符串(从系统文件选择器、第三方应用分享获取的路径大多是这种格式),不能直接传入FileInputStream,需要通过ContentResolver打开输入流,修改后的代码参考:
if (txt_file.endsWith(".txt")) { try { Log.e("TAG", "path " + txt_file); // 替换原FileInputStream逻辑,txtUri为你转换得到的Uri对象 InputStream is = getContentResolver().openInputStream(txtUri); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int bytesRead; while ((bytesRead = is.read(b)) != -1) { bos.write(b, 0, bytesRead); } byte[] bytes = bos.toByteArray(); byte[] dataToSave = Base64.encode(bytes, Base64.DEFAULT); // 用完及时关闭流 is.close(); bos.close(); } catch (IOException e) { e.printStackTrace(); } }
- 不要手动拼接存储路径,不同厂商、不同系统版本的公共存储根路径可能存在差异,必须使用系统API获取对应目录路径,避免路径不匹配问题。
3. 分区存储适配校验
Android 10(API 29)引入了分区存储机制,默认禁止应用直接访问公共目录的原始路径,可以先做临时兼容验证:在AndroidManifest.xml的application节点添加android:requestLegacyExternalStorage="true"属性,关闭分区存储限制,如果修改后问题消失,说明是分区存储适配问题,正式版本建议适配SAF框架实现文件访问,不要长期依赖兼容属性。
4. 前置存在性校验
读取文件前添加代码校验文件状态,提前定位问题:
File targetFile = new File(txt_file); if (!targetFile.exists()) { Log.e("TAG", "文件不存在"); } else if (!targetFile.canRead()) { Log.e("TAG", "无文件读取权限"); } else { // 执行读取逻辑 }
内容的提问来源于stack exchange,提问作者a awasi
相关产品推荐
相关产品推荐

