Xamarin iOS DocumentPicker: как импортировать большие файлы?
В DidPickDocument
событие UIDocumentPickerViewController
Я пытаюсь импортировать / записать выбранный файл в локальный каталог документов приложения. Это прекрасно работает с "маленькими" файлами (например, < 100 МБ), используя подклассный класс UIDocument с переопределением
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);
Но если файл больше (например, 400 МБ), приложение вылетает раньше LoadFromContents
вызывается из-за недостаточной памяти (RAM).
Таким образом, должен быть способ потоковой передачи выбранного файла непосредственно в файл. Как вы можете сделать это, используя данный NSUrl?
2 ответа
Так как у вас есть URL, нет необходимости конвертировать его в NSData
затем сохраните данные в файл. Мы можем просто использовать этот URL с 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();
Таким образом, мы можем сохранить файл в собственном каталоге документов нашего приложения.
- почему бы вам просто не клонировать файл в каталог "Документы", прежде чем читать его, а не десериализовать содержимое и повторно сериализовать его?
- Ваш код кажется действительно неэффективным. Если ваши файлы могут быть 400 МБ, вы явно не должны загружать все содержимое в память. Я предполагаю, что у вас должны быть очень большие двоичные объекты в файлах, если они могут быть 400 МБ; попробуйте mmapping файл и хранить указатели на отдельные объекты вместо этого?