为何InputFilter闭包传入长度与分页大小不符?
问题原因解析
核心区别:两个length的作用完全不同
你混淆了InputFilter中两个length参数的含义:
- 调用
readData(ofLength: pageSize)传入的128,是控制解压后输出数据的分页粒度——要求每次返回最多128字节的解压后数据。 - 数据源闭包中的
length参数,是底层LZFSE解压算法向你请求的输入压缩数据的字节数,这个值由算法内部的缓冲区大小和压缩块结构决定,和你设置的输出分页大小无关。
为什么是65536?
LZFSE作为Apple的原生压缩算法,默认使用65536字节(64KB)作为内部解压缓冲区的大小。算法需要一次性获取足够的压缩数据填满缓冲区,才能高效处理压缩块的解压逻辑——这是算法层面的性能优化策略,和你的输出分页需求没有直接关联。
你的代码实际行为符合预期
虽然数据源闭包收到的length是65536,但readData(ofLength: 128)返回的page长度应该是128字节(最后一页可能不足),这说明输出确实是按你期望的128字节分页的。你可以打印page.count验证这一点。
若想控制输入读取粒度(非必要)
如果一定要让数据源闭包每次只读取固定大小的压缩数据,可以忽略传入的length参数,直接返回固定长度的子数据:
let inputFilter = try! InputFilter(.decompress, using: .lzfse) { _ -> Data? in let rangeLength = min(128, decompressBufferSize - decompressIndex) guard rangeLength > 0 else { return nil } let subdata = compressedData.subdata(in: decompressIndex ..< decompressIndex + rangeLength) decompressIndex += rangeLength return subdata }
这种情况下,InputFilter会自动多次调用闭包获取数据,直到凑够算法需要的压缩块,最终输出依然会按你设置的128字节分页返回。
内容的提问来源于stack exchange,提问作者Yasic
相关产品推荐
相关产品推荐

