Android 12中DocumentFile.toString()不返回文本内容,如何获取文件文本?
Android 12+ 从DocumentFile读取文本文件的最简实现
注意:
DocumentFile.toString()返回文件内容从未被官方纳入规范,Android 12之前的对应表现仅为底层实现巧合,不具备版本兼容性,不可作为稳定方案依赖。
核心逻辑
通过DocumentFile实例的uri属性调用系统ContentResolver打开文件输入流,直接读取流内容转字符串即可,全程兼容全版本Android系统。
代码实现
Kotlin 版本(最简,自动资源管理)
// 扩展函数,直接给DocumentFile新增读文本能力 fun DocumentFile.readText(context: Context, charset: Charset = Charsets.UTF_8): String { return requireNotNull(context.contentResolver.openInputStream(uri)) { "无法打开目标文件的输入流,请检查文件是否存在及读取权限是否正常" }.use { inputStream -> inputStream.reader(charset).readText() } } // 调用示例 val fileContent = myDocumentFile.readText(context)
Java 版本
import java.io.InputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import android.content.Context; import androidx.documentfile.provider.DocumentFile; public String readDocumentFileText(Context context, DocumentFile documentFile) throws IOException { try (InputStream inputStream = context.getContentResolver().openInputStream(documentFile.getUri())) { if (inputStream == null) { throw new IllegalArgumentException("无法打开目标文件输入流"); } return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); } }
如果需要兼容Android 7及以下不支持readAllBytes的场景,可以替换成如下实现:
public String readDocumentFileText(Context context, DocumentFile documentFile) throws IOException { try (InputStream inputStream = context.getContentResolver().openInputStream(documentFile.getUri())) { if (inputStream == null) { throw new IllegalArgumentException("无法打开目标文件输入流"); } StringBuilder sb = new StringBuilder(); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) != -1) { sb.append(new String(buffer, 0, len, StandardCharsets.UTF_8)); } return sb.toString(); } }
注意事项
- 调用前请确保已经获取目标
DocumentFile的读取权限,否则会抛出安全异常 - 大于1M的文本文件不建议直接使用该方法读取,避免占用过高内存触发OOM,建议分片处理
- 读取非UTF-8编码的文件时,自行传入对应字符集参数即可
内容的提问来源于stack exchange,提问作者AndreaF
相关产品推荐
相关产品推荐

