【问题标题】:Xamarin iOS DocumentPicker: How to import large files?Xamarin iOS DocumentPicker:如何导入大文件?
【发布时间】: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 做到这一点?

【问题讨论】:

    标签: ios xamarin uidocument uidocumentpickerviewcontroller


    【解决方案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。
      猜你喜欢
      • 1970-01-01
      • 2018-02-27
      • 2022-01-23
      • 1970-01-01
      • 2014-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多