一.断点续传的原理:
断点续传的原理:每次在想服务器请求下载数据的同时,要告诉服务器从整个下载文件的数据流的某个还未下载的位置开始下载,然后服务器就返回从哪个位置开始的数据流
二.断点续传的实现:
第一步:先声明一些属性
fileprivate var totalSize: Int64 = 0 // 总大小
fileprivate var currentSize: Int64 = 0 // 当前大小
fileprivate var fileName: String? // 文件名
fileprivate var fullPath: String? // 文件路劲
fileprivate var handle: FileHandle? // 句柄
fileprivate var connection: NSURLConnection?
第二步:创建URL和请求
关键是设置请求头
// 下载文件
func urlConnectionDownload(_ url: String) -> NSURLConnection? {
var request = URLRequest(url: URL(string: url)!)
// 设置请求头信息
/*
bytes=0-1000 表示下载0-1000的数据
bytes=0- 表示从0开始下载直到下载完毕
bytes=100- 表示从100开始下载直到下载完毕
*/
request.setValue("bytes=\(currentSize)", forHTTPHeaderField: "Range")
// 发送异步请求
connection = NSURLConnection(request: request, delegate: self)
return connection
}
// 取消下载文件
func urlConnectionCacel() {
connection?.cancel()
}
第三步:设置代理NSURLConnectionDataDelegate
第四步:实现代理NSURLConnectionDataDelegate方法
// 接收到响应头信息的时候就会调用(最先调用的方法),只会调用一次
func connection(_ connection: NSURLConnection, didReceive response: URLResponse) {
print("didReceive response")
// 判断是否已经下载过了
if currentSize > 0 {
// 已经下载过的话,就不需要再次接受response了
return
}
// 文件的总大小
totalSize = response.expectedContentLength
// 得到的文件名称
fileName = response.suggestedFilename
// 边接收数据边写文件到沙盒中
// 1. 获取文件的全路径
if let cache = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).last {
let nsCache = cache as NSString
fullPath = nsCache.appendingPathComponent(fileName!)
// 创建一个空的文件
FileManager.default.createFile(atPath: fullPath!, contents: nil, attributes: nil)
// 创建句柄
handle = FileHandle(forWritingAtPath: fullPath!)
}
}
func connection(_ connection: NSURLConnection, didReceive data: Data) {
print("didReceive data")
// 把文件句柄移动到文件的末尾
handle?.seekToEndOfFile()
// 使用文件句柄写数据
handle?.write(data)
currentSize += data.count
print(currentSize / totalSize)
}
func connectionDidFinishLoading(_ connection: NSURLConnection) {
print("didFinish loading")
print(fullPath!)
handle?.closeFile()
handle = nil
}