Невозможно переместить файл после загрузки фона: "Нет такого файла"
У меня есть приложение, использующее backgroundSessionConfiguration
экземпляр NSURLSession
для обработки некоторых NSURLSessionDownloadTask
задач. Задачи создаются правильно и завершают загрузку, но в URLSession:downloadTask:didFinishDownloadingToURL:
, когда я перехожу, чтобы переместить загруженный файл из location
в постоянное место на диске, я иногда (часто читаю) получаю ошибку:
NSUnderlyingError=0x178247890 "The operation couldn’t be completed. No such file or directory"
Как будто скачанный файл очищается из временного каталога (../Library/Caches/com.apple.nsnetworkd/..), прежде чем у меня появится возможность его переместить.
Запуск операции для того же удаленного файла будет вести себя в обоих направлениях, при этом все остальные факторы будут равны, поэтому я не смог идентифицировать что-либо, что могло бы заставить его иногда работать.
В любом случае, чтобы этот файл задерживался достаточно долго, чтобы переместить его на место после его завершения?
Изменить: я также вижу это с некоторой частотой для обычных (а не фоновых) сеансов, а также
Ответы
Ответ 1
Временные файлы удаляются автоматически после выхода из этого метода, вы можете попытаться сохранить этот возвращенный файл как NSData
и сохранить его непосредственно в нужное место.
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
// Create a NSFileManager instance
NSFileManager *fileManager = [[NSFileManager alloc] init];
// Get the documents directory URL
NSArray *documentURLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [documentURLs firstObject];
// Get the file name and create a destination URL
NSString *sendingFileName = [downloadTask.originalRequest.URL lastPathComponent];
NSURL *destinationUrl = [documentsDirectory URLByAppendingPathComponent:sendingFileName];
// Hold this file as an NSData and write it to the new location
NSData *fileData = [NSData dataWithContentsOfURL:location];
[fileData writeToURL:destinationUrl atomically:NO];
}
Ответ 2
Попробуйте это
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *URLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [URLs objectAtIndex:0];
NSURL *originalURL = [[downloadTask originalRequest] URL];
if(originalURL)
destinationUrl = [documentsDirectory URLByAppendingPathComponent:[originalURL lastPathComponent]];
NSError *errorCopy;
[fileManager removeItemAtURL:destinationUrl error:NULL];
BOOL success = [fileManager copyItemAtURL:downloadURL toURL:destinationUrl error:&errorCopy];
if (success) {
} else {
}
}
Ответ 3
Включение в это с помощью Swift под iOS 8, копирование или перемещение файла не сработало.
Чтение файла temp напрямую и запись обратно работали.
Код создает изображение из загруженного изображения:
var fileHandle:NSFileHandle = NSFileHandle(forReadingAtPath: location.path!)!
var data:NSData = fileHandle.readDataToEndOfFile()
var image:UIImage = UIImage(data: data)!
imageView.image = image
Ответ 4
Это лучший способ сделать это
- (void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location{
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSArray *documentURLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSURL *documentsDirectory = [documentURLs firstObject];
// Get the file name and create a destination URL
NSString *sendingFileName = [downloadTask.response suggestedFilename];
NSURL *destinationUrl = [documentsDirectory URLByAppendingPathComponent:sendingFileName];
// Hold this file as an NSData and write it to the new location
NSData *fileData = [NSData dataWithContentsOfURL:location];
[fileData writeToURL:destinationUrl atomically:NO];
}