gzflush
按请求的刷新模式处理缓冲输出。
完整章节与共同规则 ↗2425ced89b926581 · 对应提交的原文 ↗先看本函数的前置条件和返回结果;可展开下方共同规则,查看整组接口的缓冲区与所有权要求。
按请求的刷新模式处理缓冲输出。
int ZEXPORT gzflush(gzFile file, int flush);
定义域 受限定义域:写入句柄;完整 int flush 拒绝范围。
效果: 有状态输出,可能分配内存并处理待处理零填充。
前置条件 满足共享写入句柄要求,压缩参数有效。
普通刷新模式范围为 Z_NO_FLUSH 至 Z_FINISH。
返回与保证 请求工作成功时返回 Z_OK。Z_SYNC_FLUSH 使待处理数据可供读取;
Z_FINISH 完成一个 gzip 成员。后续成功写入可开始另一个成员。
T 写出缓冲字节,不生成 gzip 尾部。句柄仍存活,仍须关闭。
错误与边缘情形: NULL、读取句柄、待处理硬错误或 0–Z_FINISH 范围外的刷新值,
返回 Z_STREAM_ERROR。分配、定位填充和系统写入失败返回已记录错误码。
有效写入句柄在验证 flush 前会清除可重试错误,因此无效刷新不总是保持状态的拒绝。
失败的 Z_FINISH 不表示成员完成;仅清除错误不足以把恢复当作全新输出。
见下述注意事项。
本组共同前提与范围
使用 gzFile 句柄进行带缓冲的 gzip 文件 I/O。打开时取得文件描述符和私有状态;
数据操作按需初始化缓冲区和编解码器状态;即使最终 I/O 失败,关闭也会释放句柄。
读取还可接受透明的未压缩输入:文件中的字节不经解压,直接作为结果交付。
| 任务 | 入口 |
|---|---|
| 打开或配置 | 打开路径、打开描述符、缓冲区大小、压缩参数 |
| 读取 | 字节、数据项、字符、回退字节、行 |
| 写入 | 字节、数据项、字符、字符串、格式化文本、刷新 |
| 位置 | 定位、回到起点、未压缩位置、文件偏移 |
| 查询或清除状态 | 文件末尾、透明模式、错误、清除错误 |
| 关闭 | 任意模式、读取句柄、写入句柄 |
本页按固定版本源码和 zlib.h 组织接口契约。各条目明确列出调用范围,
对应的完整执行要求见已登记公开目标,当前证据见进度。
超出聚焦前提只表示本契约不作保证,不自动等于 C 未定义行为(UB),也不保证一定返回错误码。
通用句柄条件
先分清两种位置。逻辑位置以未压缩字节计数;普通读写按已消费或接受的数量推进,定位还可以登记尚未执行的前移。底层文件另有物理偏移,它以文件中的字节计数。gztell 查询前者,gzoffset 查询后者。库会预读和缓冲,因此两个值通常不同;单次压缩率也不能用来换算它们。
例如,没有额外定位或字节回退时,读取句柄已向应用交付 1000 个解压字节,逻辑位置就是 1000;为了完成这些输出,底层可能已预读更靠后的压缩字节。相反,写入成功表示库接受了输入,不能据此推断这些字节已全部写入描述符。
后面的参数沿用这套单位:len 和缓冲区配置 size 按字节计;数据项接口中的 size 是每项字节数,nitems 是项数,总请求为 size * nitems 字节。offset 是有符号的未压缩字节位移;whence 指定从起点(SEEK_SET)还是当前位置(SEEK_CUR)计算。INT_MAX 是本构建中有符号 int 能表示的最大值,即 2^31 - 1。
本页把可直接重试的非阻塞停顿与其他已记录的“硬错误”分开描述。这个区别说明本次调用怎样返回;它不免除错误后的状态、重试和清理要求。
本页使用默认 x86_64 Linux 构建。int 和 unsigned 为 32 位。
long、z_off_t、z_off64_t 和 z_size_t 为 64 位。大文件声明已启用。
这里普通入口和 *64 入口的偏移范围相同。其他配置需要单独契约。
gzopen_w 仅适用于 Windows,下文另行限定其范围。
受限定义域指满足下列通用要求的普通用法:
- 非 NULL 句柄由成功打开返回、仍存活且尚未关闭。串行使用它,调用者不修改其私有状态。
- 读取或写入句柄具有入口指定的访问模式。NULL 和错误模式的拒绝情形分别说明。 已失效或任意指针不在本定义域内;检查模式字段不等于验证指针。
- 缓冲区覆盖请求的可读或可写范围,并与句柄拥有的内存分离。 字符串具有可读的终止 NUL。调用者保留这些对象的所有权。
- 位置运算和请求范围能由指定 C 类型表示。下述契约仍包括显式的超大请求和乘法溢出拒绝。
- 描述符在关闭前属于句柄。调用期间,没有其他操作改变其数据或位置。 操作系统失败和分配失败仍可能发生;成功打开不保证后续 I/O 成功。
每个入口均带定义域标签。“完整标量范围”仅在上述指针和生存期要求下, 适用于所指明的标量参数。文档中的限制不免除已知失败路径的义务。 特别地,部分读取错误和字节回退形成的负位置仍属于未改变的公开目标。
效果。 读、写、打开、定位、控制和关闭均为有状态操作,包括没有调用者输出缓冲区的操作。
位置查询(gztell、gzoffset)和文件末尾查询(gzeof)读取状态;gzerror 还可能写入可选错误码输出。
gzdirect 可读取文件并分配内存,因此也是有状态操作。
stateDiagram-v2
state "新建句柄" as Fresh
state "已开始数据处理" as Active
state "已关闭" as Closed
[*] --> Fresh: 成功打开
Fresh --> Active: 首次 I/O 或格式检查
Active --> Active: 读、写、定位、控制
Fresh --> Closed: 关闭
Active --> Closed: 关闭,包括最终 I/O 失败
Closed --> [*]
格式与缓冲。 打开时不对载荷执行 I/O。缓冲区和编解码器状态按需分配, 默认请求的缓冲区大小为 8192 字节。请求大小是配置量,实际内部存储还包括下述双倍缓冲区和编解码器状态。首次使用或后续解压期间都可能分配失败。 即使最终 I/O 失败,关闭也释放拥有的分配。
普通读取句柄根据合理的四字节头部识别 gzip;否则原样返回输入。
空输入属于透明输入。非阻塞输入在获得四字节前停顿时,检测保持等待。
一个 gzip 成员是一段带有自身头部、压缩数据和尾部校验信息的完整流;一个文件可以顺序放置多个成员。读取输出按顺序拼接各成员的未压缩数据。若尝试解码下一个成员时,在格式错误前未产生输出,
则忽略尾随的非成员数据。G 要求 gzip;T 选择透明输出,不能用于读取。
读取结果。 读取按已消费字节数推进未压缩位置,包括最终的部分数据项。
已缓冲字节可能在已记录错误被报告之前返回。gzeof 表示曾尝试读取可用数据之后的内容,
而不只是已交付最后一个字节。gzerror 区分 EOF、损坏(Z_DATA_ERROR)、
截断(Z_BUF_ERROR)、分配失败(Z_MEM_ERROR)和系统失败(Z_ERRNO)。
零长度读取不消费输入,也不执行待处理定位。
写入结果。 成功表示句柄已接受输入;数据仍可能在缓冲区内。 后续刷新或关闭仍可能失败。硬错误可能在消费一个前缀后返回失败; 仅凭返回值不总能确定重试偏移。非阻塞停顿则可能返回至今已消费的数量。
错误通常持续到被清除。已记录的非阻塞停顿允许下次数据 I/O 重试。
定位和回到起点仍拒绝该已记录的 Z_ERRNO。构造错误消息本身可能失败,
并将错误码改为 Z_MEM_ERROR。errno 只对关联的系统失败有意义,
不能普遍解释每个失败的 API 调用。
源码为 gzlib.c、gzread.c、
gzwrite.c、gzclose.c 和
zlib.h。抽象契约位于 Api/Gz.lean。
具体目标位于 GzOpen、
GzRead、GzWrite、
GzControl 和
GzClose。翻译在 ZlibF/Zlib/ 中保留 C 名称。
形式化约定
ZlibF.Spec.Public.Goal.gzflush
证明状态:未完成 · 证明记录与剩余工作
/-- `int gzflush(gzFile file, int flush)`.
Finish pending zeros and flush the encoder. Invalid modes and flush values return a stream
error. Z_FINISH completes a gzip member; later writes can start another member. -/
def Goal.gzflush : Prop :=
(∀ h fs flush, Zlib.Gzwrite.gzflush none flush fs h = .ok ((Z_STREAM_ERROR, fs), h)) ∧
(∀ h fs i s flush, GzReachable h fs i → GzValid h i s →
∃ rc fs' after s',
Zlib.Gzwrite.gzflush (some (.in_gzstate_x i)) flush fs h = .ok ((rc, fs'), after) ∧
GzStateFrame h after fs fs' i s s' [] ∧
(s.mode ≠ GZ_WRITE ∨ flush.toInt < 0 ∨ 4 < flush.toInt → rc = Z_STREAM_ERROR) ∧
(s.mode = GZ_WRITE → s.err = Z_OK ∨ s.again ≠ 0 →
0 ≤ flush.toInt → flush.toInt ≤ 4 → rc = s'.err) ∧
(NoAllocationFailure h → WriterReady s → WriteRoom fs s 0 →
0 ≤ flush.toInt → flush.toInt ≤ 4 → rc = Z_OK ∧ s'.skip = 0))相关定义与源码 ↗