首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当使用内容显示时,保存文件的正确方法是什么?

当使用内容显示时,保存文件的正确方法是什么?
EN

Stack Overflow用户
提问于 2018-06-24 18:15:46
回答 1查看 965关注 0票数 5

我使用以下意图允许用户选择文件应该保存的位置:

代码语言:javascript
复制
// https://developer.android.com/guide/topics/providers/document-provider
var intent = new Intent(Intent.ActionCreateDocument);
intent.AddCategory(Intent.CategoryOpenable);
intent.SetType("image/png");
intent.PutExtra(Intent.ExtraTitle, "myfile");
StartActivityForResult(Intent.CreateChooser(intent, "Select Save Location"), 43);

它创建文件并返回文件的uri:

代码语言:javascript
复制
content://com.android.providers.downloads.documents/document/436

但是现在我被抛在脑后,因为文档的那一节以

在创建新文档之后,您可以在onActivityResult()中获取它的URI,以便可以继续写入它。

我不知道该怎么做。因为我的结果是使用content方案,所以我不能把它当作一个常规的Java.IO.File,然后把它写到磁盘上。那么,如何将文件保存到我所拥有的内容uri中呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-24 18:56:47

当您在OnActivityResult中获得内容Uri时,您拥有对该Uri的临时权限(从而具有写入访问权限),因此您可以在写模式下打开一个基于包的文件描述符,从该包的文件描述符中创建一个输出流,并编写您需要的任何内容。

示例将资产流写入用户选择的文件:

代码语言:javascript
复制
protected async override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
    if (resultCode == Result.Ok && requestCode == 43)
    {
        var buffer = new byte[1024];
        using (var pFD = ContentResolver.OpenFileDescriptor(data.Data, "w"))
        using (var outputSteam = new FileOutputStream(pFD.FileDescriptor))
        using (var inputStream = Assets.Open("somePicture.png"))
        {
            while (inputStream.CanRead && inputStream.IsDataAvailable())
            {
                var readCount = await inputStream.ReadAsync(buffer, 0, buffer.Length);
                await outputSteam.WriteAsync(buffer, 0, readCount);
            }
        }

    }
    base.OnActivityResult(requestCode, resultCode, data);
}

更新(业绩):

只是一个FYI,如果您正在保存/流大文件,请避免在流上读取和写入异步版本,只需旋转一个线程(或者通过Task.Run从线程池中使用一个线程)。

注意:这将使总是更快,因为所有的异步/等待开销都是这样的,并且类似于我通常是如何做的(根据文件大小,通常要快2x(+) )。

代码语言:javascript
复制
if (resultCode == Result.Ok && requestCode == 43)
{
    await Task.Run(() =>
    {
        // Buffer size can be "tuned" to enhance read/write performance
        var buffer = new byte[1024]; 
        using (var pFD = ContentResolver.OpenFileDescriptor(data.Data, "w"))
        using (var outputSteam = new FileOutputStream(pFD.FileDescriptor))
        using (var inputStream = Assets.Open("her.png"))
        {
            while (inputStream.CanRead && inputStream.IsDataAvailable())
            {
                var readCount = inputStream.Read(buffer, 0, buffer.Length);
                outputSteam.Write(buffer, 0, readCount);
            }
        }
    });
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51012702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档