- 1 FileTool.swift 实现获取文件的大小/移动文件/文件是否存在等等的判断
- 2 DownLoader.swift 是下载文件的主类
- 3在Controller中创建DownLoader对象,即可使用
首先是 下载的类 DownLoader.swift
import UIKitprivate let kCachePath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.cachesDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).firstprivate let kTempPath = NSTemporaryDirectory()class DownLoader: NSObject {fileprivate var downLoadedPath : String?fileprivate var downLoadingPath : String?fileprivate var outputStream : OutputStream?fileprivate var tmpSize : CLongLong = 0fileprivate var totalSize : CLongLong = 0fileprivate lazy var session : URLSession = {let config = URLSessionConfiguration.defaultlet session = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)return session}()func downLoader(url : NSURL) {let fileName = url.lastPathComponentguard url.lastPathComponent != nil else {print("url有问题")return}self.downLoadingPath = kTempPath + "/" + fileName!self.downLoadedPath = kCachePath! + "/" + fileName!//检查当前路径是否已经下载了该文件if FileTool.fileExists(filePath: self.downLoadedPath!) {print("文件以及下载完成")return}print(self.downLoadingPath ?? "")//如果没有下载完成 就看是否有临时文件if !FileTool.fileExists(filePath: self.downLoadingPath!) {//不存在的话 直接开始下载self.downLoadWithURL(url as URL, 0)return;}//已经下载了的 先计算 下载的大小,然后继续下载tmpSize = FileTool.fileSize(self.downLoadingPath!)self.downLoadWithURL(url as URL, tmpSize)}// MARK:- 开始请求资源func downLoadWithURL(_ url : URL, _ offset : CLongLong) {var request = NSURLRequest(url: url, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 0) as URLRequestrequest.setValue("bytes=%lld-", forHTTPHeaderField: "Range")let dataTask = self.session.dataTask(with: request)dataTask.resume()}}extension DownLoader : URLSessionDataDelegate {func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Swift.Void){print(response)let resp = response as! HTTPURLResponse// self.totalSize = resp.allHeaderFields["Content-Length"] as! CLongLong?// self.totalSize = String(resp.allHeaderFields["Content-Length"]).components(separatedBy: "/").last).CLongLonglet string = resp.allHeaderFields["Content-Length"] as! Stringlet stri : String = string.components(separatedBy: "/").last!self.totalSize = CLongLong(stri)!// 比对本地大小, 和 总大小if (self.tmpSize == self.totalSize) {// 1. 移动到下载完成文件夹print("移动文件到下载完成")FileTool.moveFile(self.downLoadingPath!, self.downLoadedPath!)// 2. 取消本次请求completionHandler(URLSession.ResponseDisposition.cancel);return;}if (self.tmpSize > self.totalSize) {// 1. 删除临时缓存print("删除临时缓存")FileTool.removeFile(self.downLoadingPath!)// 2. 从0 开始下载print("重新开始下载")self.downLoader(url: resp.url! as NSURL)// [self downLoadWithURL:response.URL offset:0];// 3. 取消请求completionHandler(URLSession.ResponseDisposition.cancel);return;}// 继续接受数据// 确定开始下载数据self.outputStream = OutputStream(toFileAtPath: self.downLoadingPath!, append: true)self.outputStream?.open()completionHandler(URLSession.ResponseDisposition.allow);}func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data){var buffer = [UInt8](repeating: 0, count: data.count)data.copyBytes(to: &buffer, count: data.count)self.outputStream?.write(buffer, maxLength: data.count)// let uint8Ptr = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)// uint8Ptr.initialize(from: data)// let rawPtr = UnsafeRawPointer(uint8Ptr)// self.outputStream?.write(rawPtr, maxLength: da.length)}func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?){print("请求完成")if (error == nil) {// 不一定是成功// 数据是肯定可以请求完毕// 判断, 本地缓存 == 文件总大小 {filename: filesize: md5:xxx}// 如果等于 => 验证, 是否文件完整(file md5 )}else {print("有问题")}self.outputStream?.close()}}
其次是文件的工具类 FileTool.swift
import UIKitclass FileTool: NSObject {// MARK:- 判断文件目录是否存在class func fileExists(filePath : String) -> Bool {if (filePath.characters.count == 0) {return false}return FileManager.default.fileExists(atPath: filePath)}// MARK:- 获取文件的大小class func fileSize(_ filePath : String) ->CLongLong{if !self.fileExists(filePath: filePath) {return 0}let fileInfo = try! FileManager.default.attributesOfItem(atPath: filePath)return fileInfo[FileAttributeKey.size] as! CLongLong}// MARK:- 移动文件class func moveFile(_ fromPath : String , _ toPath : String){if self.fileSize(fromPath) == 0 {return}try! FileManager.default.moveItem(atPath: fromPath, toPath: toPath)}class func removeFile(_ filePath : String){try! FileManager.default.removeItem(atPath: filePath)}}
使用
fileprivate var downLoader = DownLoader()override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {let url = NSURL(string: "http://free2.macx.cn:8281/tools/photo/SnapNDragPro418.dmg")self.downLoader.downLoader(url: url!)}
