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

Android 11中跨路径复制文件后输出文件为空的问题排查求助

解决Android 11跨路径文件复制后文件为空的问题

嘿,我仔细看了你的代码和问题描述,发现了几个关键问题,正是这些问题导致复制后的文件为空,咱们一步步来解决:

1. 文件Uri的编码错误

你第一个Uri里的编码存在问题:

Uri muri = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3Aagora%2file.txt");

这里的%2是不完整的URL编码,路径分隔符/的正确编码应该是%2F,所以修正后的源文件Uri应该是:

Uri muri = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3Aagora%2Ffile.txt");

错误的编码会导致系统无法正确识别文件路径,自然读不到任何文件内容。

2. 错误使用DocumentFile.fromTreeUri处理文件Uri

DocumentFile.fromTreeUri()是专门用来处理目录Tree Uri的API,而你的muri是单个文件的Uri,用这个方法会得到无效的DocumentFile对象,后续调用openInputStream()时要么拿到空流,要么根本读不到数据。处理单个文件Uri应该用DocumentFile.fromSingleUri():

DocumentFile mfile = DocumentFile.fromSingleUri(MainActivity.this, muri);

3. 潜在优化:流处理与异常排查

另外,你的复制方法可以添加一些空值判断和数据刷入逻辑,避免空指针同时确保数据完全写入磁盘,还建议打印异常信息方便后续排查:

修正后的完整代码

// 修正编码后的源文件Uri
Uri muri = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3Aagora%2Ffile.txt");
Uri uri2 = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAlarms");

// 用fromSingleUri处理单个文件Uri
DocumentFile mfile = DocumentFile.fromSingleUri(MainActivity.this, muri);
DocumentFile mfile1 = DocumentFile.fromTreeUri(MainActivity.this, uri2);
// 改用标准MIME类型text/plain,避免系统识别异常
mfile1 = mfile1.createFile("text/plain", "file.txt");
uri2 = mfile1.getUri();

if (copyFileFromUri2(MainActivity.this, muri, uri2)) {
    showMessage("file copied successfully");
} else {
    showMessage("failed to copy the file !");
}

优化后的复制方法

public boolean copyFileFromUri2(Context context, Uri fileUri, Uri targetUri) {
    InputStream fis = null;
    OutputStream fos = null;
    try {
        ContentResolver content = context.getContentResolver();
        fis = content.openInputStream(fileUri);
        // 先检查输入流是否有效
        if (fis == null) {
            return false;
        }
        fos = content.openOutputStream(targetUri);
        if (fos == null) {
            return false;
        }
        // 增大缓冲区提升复制效率
        byte[] buff = new byte[4096];
        int length = 0;
        while ((length = fis.read(buff)) != -1) {
            fos.write(buff, 0, length);
        }
        // 确保所有数据写入磁盘
        fos.flush();
    } catch (IOException e) {
        // 打印异常信息方便排查
        e.printStackTrace();
        return false;
    } finally {
        // 安全关闭流
        try {
            if (fis != null) fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (fos != null) fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return true;
}

额外测试建议

  • 测试前确认源文件agora/file.txt确实存在,且你的App已经获取了该文件所在目录的访问权限
  • 可以在复制前先判断mfile.exists(),确保源文件可访问

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 12:23:11