【问题标题】:Downloaded file does not exist下载的文件不存在
【发布时间】:2015-06-10 08:16:59
【问题描述】:

我使用this tutorial在后台下载文件

下载文件时,有 2 个函数通知我们。我按发生的时间顺序写它们:

1) - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL;

2) - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error;

在函数1中,我检查下载的文件是否仍然存在。

在函数2中,我检查下载的文件不存在。我认为是被iOS系统删除了。​​

你能解释一下为什么吗? 谢谢

【问题讨论】:

  • 你从哪里得到下载的文件路径?
  • 你检查文件路径是否存在于finder中?
  • @trick14:那么在这种情况下,正确的文档路径是什么?
  • 查看document
  • @grhnkdlk:我在模拟器里查了一下,没有文件。所以,我想知道我的文件下载后在哪里。

标签: ios objective-c


【解决方案1】:
- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location

根据iOS Developer Library

session:包含已完成下载任务的会话。

downloadTask:已完成的下载任务。

location :临时文件的文件 URL。由于该文件是临时文件,因此您必须打开文件进行读取或将其移动到应用程序沙箱容器目录中的永久位置,然后才能从此委托方法返回。 如果您选择打开文件进行读取,您应该在另一个线程中进行实际读取以避免阻塞委托队列。

所以是的,下载的文件 临时。如果您想将下载的文件保留在您的应用程序中,您应该将此数据保存在NSDocuments 路径下。

更多信息ray wenderlich's blog

任务完成后,调用 URLSession:downloadTask:didFinishDownloadingToURL:。这是您可以将文件从临时位置保存到永久位置的时候。

当您使用此方法时,将下载的数据写入您的文件夹。但不要阻塞线程。

【讨论】:

  • 我需要创建另一个线程来将临时下载的文件复制到我的应用程序的沙箱吗? (如果临时文件很大)
  • 是的,您应该创建另一个线程来复制进程。这必须是异步任务:)
  • 创建另一个线程(异步任务)进行复制是错误的,因为在此方法结束时 (URLSession:(NSURLSession *)session downloadTask ....) 临时文件被删除。当我们的线程尝试复制时,此方法会尝试删除文件。
  • @chipbk10 Here is an example 从后台线程复制临时文件。
【解决方案2】:

我遇到了同样的问题。

尝试在对fileExistsAtPath: 的调用中使用[downloadURL path] 而不是[downloadURL absoluteString]

像这样

BOOL exist1 = [fileManager fileExistsAtPath:[downloadURL path]];

请参阅fileExistsAtPath: returning NO for files that exist 了解更多信息:-)

【讨论】:

  • 不,这不是我的问题。请查看我更新的问题。
  • 一年...那是相当长的时间 :) 很高兴你能成功
【解决方案3】:

尝试在同一个线程中复制文件内容。

AudioPlayerViewController: UIViewController, URLSessionDelegate, URLSessionDataDelegate, URLSessionDownloadDelegate{

var defaultSession: URLSession!
    var downloadTask: URLSessionDownloadTask!

func downloadFunc()
{
                defaultSession = Foundation.URLSession(configuration: .default, delegate: self, delegateQueue: nil)
                downloadTask = defaultSession.downloadTask(with: audioUrl)
                downloadTask.resume()
}

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64,

 totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

    DispatchQueue.main.async {
        self.downloadProgressBar.setProgress(Float(totalBytesWritten)/Float(totalBytesExpectedToWrite), animated: true)

        let progressValue = Int(100 * totalBytesWritten / totalBytesExpectedToWrite)
        self.downloadProgressLabel.text = "\(progressValue)%"
    }
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        do {
            let documentsDirectoryURL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

            let destinationUrl = documentsDirectoryURL.appendingPathComponent("destination_path.mp3")

            // after downloading your file you need to move it to your destination url
            try FileManager.default.copyItem(at: location, to: destinationUrl)
            print("File moved to documents folder")

        } catch let error as NSError {
            print(error.localizedDescription)
        }

}

【讨论】:

  • 更多细节将使这成为更好的答案。他们应该怎么做?为什么这能回答他们为什么会看到他们所看到的行为的问题?
  • 更新了新答案。
  • copyItem 功能帮助我解决了我的问题 :) 花了我几个小时,感谢您和您的解决方案,Krishna。
【解决方案4】:

link provided by you 中,他们将文件保存在文档目录中,因此您可以通过 NSLog 语句在 iOS 模拟器中检查 sample link 中给出的变量 destinationURL 是否应该帮助你。

NSLog(@"my doc directory path = %@",destinationURL);

【讨论】:

    猜你喜欢
    • 2019-06-16
    • 1970-01-01
    • 2015-10-31
    • 2021-09-09
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    相关资源
    最近更新 更多