如何分块从API接收数据?实现21字节块读取1.6MB接口文件
按21字节分块读取API文件的Swift实现
我来帮你搞定这个分块读取的问题!全量读取哪怕1.6MB的文件,都会等所有数据下载完才开始处理,而且一次性把所有数据塞进内存,自然会觉得耗时久。换成分块读取的话,我们可以边下载边处理,每攒够21字节就处理一块,既能减少等待时间,也能降低内存占用。
实现核心是用URLSessionDataDelegate的代理机制,在数据下载过程中逐步接收、累积并拆分数据块:
步骤1:创建分块处理管理器
我们需要一个对象来跟踪未处理的累积数据,同时实现分块逻辑:
class LogChunkHandler: NSObject, URLSessionDataDelegate { // 用来暂存还没凑够21字节的数据 private var accumulatedData = Data() // 固定的块大小 private let chunkSize = 21 func startLogDownload() { guard let url = URL(string: httpString + "log.bin") else { print("无效的请求URL") return } let request = URLRequest(url: url) // 创建带代理的URLSession,确保能实时接收数据块 let session = URLSession(configuration: .default, delegate: self, delegateQueue: .main) let task = session.dataTask(with: request) task.resume() } // 每次收到服务器返回的数据时触发 func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { // 把新收到的数据追加到累积池里 accumulatedData.append(data) // 循环拆分出完整的21字节块 while accumulatedData.count >= chunkSize { // 取出前21字节的完整块 let chunk = accumulatedData.prefix(chunkSize) // 处理这个块(替换成你的业务逻辑) processChunk(chunk) // 从累积池里移除已经处理完的部分 accumulatedData.removeFirst(chunkSize) } } // 下载完成后,处理剩下的不足21字节的收尾数据 func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { print("下载失败:\(error.localizedDescription)") return } // 如果还有剩余的零散数据,按需处理 if !accumulatedData.isEmpty { print("处理剩余零散数据(大小:\(accumulatedData.count)字节):\(accumulatedData)") processChunk(accumulatedData) } print("所有数据下载并分块处理完成") } // 自定义的块处理方法,你可以在这里做解析、存储等操作 private func processChunk(_ chunk: Data) { // 示例:打印块的基本信息,替换成你的实际逻辑 print("处理一个数据块,大小:\(chunk.count)字节,内容:\(chunk)") } }
步骤2:调用分块处理器
在需要触发下载的地方,直接初始化并启动即可:
let logHandler = LogChunkHandler() logHandler.startLogDownload()
关键细节说明
- 代理方法
didReceive data会在下载过程中多次触发,每次返回一小段数据,我们通过累积池凑够21字节就处理,不用等全部下载完成。 - 下载结束后一定要处理剩余的零散数据,避免遗漏最后一部分内容。
- 这种流式处理方式能让你在数据下载的同时就开始业务处理,大大减少整体耗时的感知。
内容的提问来源于stack exchange,提问作者user9413278
相关产品推荐
相关产品推荐

