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

Android端通过Storage Access Framework保存OneDrive文件损坏解决方案求助

问题根因

该问题属于OneDrive的Storage Access Framework(SAF)实现缺陷:当通过openOutputStream(Uri)打开文件写入流时,OneDrive不会自动截断原文件末尾超出新写入内容长度的部分。如果新内容体积小于原文件,原文件末尾的多余内容就会残留,最终出现你观察到的内容错误。该逻辑和本地存储、其他云盘的SAF实现不一致。

修复方案

不需要单独适配OneDrive,修改写入逻辑即可全局兼容所有存储提供商:

方案1(推荐,适配Android 7.0+)

打开输出流时显式指定写入+截断模式"wt",会直接清空原文件全部内容后再写入新内容,修改保存逻辑的代码如下:

binding.buttonSave.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        if (OpenFileUri == null)
            return;
        // 第二个参数传入"wt"表示w写入,t截断原有内容
        try (OutputStream mOutputStream = getActivity().getContentResolver().openOutputStream(OpenFileUri, "wt")) {
            try (PrintWriter p = new PrintWriter(mOutputStream)) {
                String t = binding.editBox.getText().toString();
                p.print(t); // 注意这里改成print不要用println,避免额外多写一个换行符
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
});

注:原代码中使用println(t)会额外在内容末尾加一个换行符,和用户输入的原始内容不一致,建议替换为print(t)。

方案2(兼容Android 7.0以下版本)

如果需要支持更低系统版本,可以写完内容后手动截断文件到新内容的长度:

binding.buttonSave.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        if (OpenFileUri == null)
            return;
        String content = binding.editBox.getText().toString();
        byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
        try (OutputStream mOutputStream = getActivity().getContentResolver().openOutputStream(OpenFileUri)) {
            mOutputStream.write(contentBytes);
            mOutputStream.flush();
            // 手动截断文件到新内容的长度
            try (ParcelFileDescriptor pfd = getActivity().getContentResolver().openFileDescriptor(OpenFileUri, "rw")) {
                if (pfd != null) {
                    Os.ftruncate(pfd.getFileDescriptor(), contentBytes.length);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:36:06