You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何分块从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:17:06