小编Ali*_* sh的帖子

如何使用android存储访问框架正确覆盖文件内容

>> 背景

我想使用 SAF(存储访问框架字)将我的应用程序的数据文件保存到用户在存储介质上所需的位置。我首先在应用程序专用文件夹中创建文件,然后将其复制到用户从文件选择器对话框中选择的文件(代码稍后发布)。

此过程适用于新文件但对于现有文件,尽管文件选择器会警告覆盖文件,但在写入之前不会删除最终文件。

通过计算写入的字节数并使用十六进制编辑器调查文件,代码将正确的字节写入输出流,但是:如果现有文件的字节数多于要写入的字节数,则最终覆盖的文件已损坏(实际上并未损坏,请参阅下一节进行澄清),如果现有的字节数少于要写入的字节数,则最终覆盖的文件是正确的。

>> 更多细节和代码

我使用下面的代码来显示问题(jpg 为示例):我将尝试使用两个文件:

file1.jpg 166,907 bytes
file2.jpg 1,323,647 bytes
file3.jpg The final file with variable size
Run Code Online (Sandbox Code Playgroud)

首先,我将把 file1 复制到用户选择的名为 file3 的文件夹(目标文件),然后用 file2 覆盖它,最后我将用 file1 再次覆盖它。看看代码是什么以及会发生什么:

调用文件选择器的代码:

val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
    addCategory(Intent.CATEGORY_OPENABLE)
    type = "image/jpeg"
}
startActivityForResult(intent, request)
Run Code Online (Sandbox Code Playgroud)

现在在 onActivityResult() 我处理数据如下:

contentResolver.openOutputStream(fileUri)?.use {output->
        val input = FileInputStream(File(getExternalFilesDir(null),"Pictures/file1.jpg"))
    // file1.jpg for first run, file2.jpg for 2nd run and file1.jpg again for 3rd run     
        copyStream(input, output)

    }
Run Code Online (Sandbox Code Playgroud)

以及复制流的代码:

@Throws(IOException::class)
fun copyStream(input: InputStream, output: …
Run Code Online (Sandbox Code Playgroud)

android overwrite fileoutputstream storage-access-framework

4
推荐指数
2
解决办法
1655
查看次数