Xamarin iOS DocumentPicker:如何导入大文件?

Posted

技术标签:

【中文标题】Xamarin iOS DocumentPicker:如何导入大文件?【英文标题】:Xamarin iOS DocumentPicker: How to import large files? 【发布时间】:2018-04-22 10:13:07 【问题描述】:

UIDocumentPickerViewControllerDidPickDocument 事件中,我尝试将所选文件导入/写入应用程序的本地文档目录。 这适用于“小”文件(例如

 public override bool LoadFromContents(NSObject contents, string typeName, out NSError outError)
    

       outError = null;

        if (contents != null)
        
            Content = ((NSData)contents).ToArray();

        

...

...并通过调用

 MySubclassedDoc mySubclassedDoc = new MySubclassedDoc (nsurl);
 bool success = await mySubclassedDoc.OpenAsync();
 File.WriteAllBytes("targetFile.xyz", mySubclassedDoc.Content);

但如果文件较大(例如 400MB),应用程序在调用 LoadFromContents 之前由于内存 (RAM) 不足而崩溃。

因此需要有一种方法可以流式传输所选文件直接到文件。 如何使用给定的 NSUrl 做到这一点?

【问题讨论】:

【参考方案1】:

既然你已经得到了 url,就没有必要将它转换成NSData 然后将数据存储到一个文件中。我们可以将此网址与NSFileManager 一起使用,例如:

url.StartAccessingSecurityScopedResource();
string docPath = NSSearchPath.GetDirectories(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User)[0];
string filePath = Path.Combine(docPath, "fileName.type");

NSError error;

NSFileManager fileManager = new NSFileManager();
fileManager.Copy(url.Path, filePath, out error);
url.StopAccessingSecurityScopedResource();

这样我们就可以将文件存储到我们应用自己的文档目录中了。

【讨论】:

【参考方案2】: 为什么不直接将文件克隆到 Documents 目录,然后再读取它,而不是反序列化并重新序列化内容? 您的代码似乎效率很低。如果您的文件可以是 400MB,那么您显然不应该将所有内容都加载到内存中。我猜你的文件中必须有非常大的二进制对象,如果它们可以是 400MB 的话;尝试映射文件并存储指向单个对象的指针?

【讨论】:

我一直关注 UiDocument(在访问从各种网站上的文档选择器返回的文件时建议使用 UiDocument,例如 xamarin 网站),所以我没有看到使用 StartAccessingSecurityScopedResource 和简单副本的简单解决方案a 到 b。

以上是关于Xamarin iOS DocumentPicker:如何导入大文件?的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin SQLite教程Xamarin.iOS项目添加引用

Xamarin.Forms 是 Xamarin.Android、Xamarin.IoS 和 Xamarin.Win 的简单总和吗?

使用Xamarin Effect删除Xamarin.iOS中TextEntry上的圆角

Xamarin.iOS 和 RFComm

Xamarin.IOS 和 Signalr 推送通知

有哪些ios或android应用是用xamarin开发的