API 总览
公共模块是 vfp_reader。应用通常只需要导入 VfpReader 与 VfpError;需要读取颜色条目或在类型注解中使用结果时再导入 PaletteEntry、BlockEntry。
from vfp_reader import BlockEntry, PaletteEntry, VfpError, VfpReader
| 对象 | 作用 |
|---|---|
VfpReader | 打开一个 VFP 并执行读取、验证、导出 |
PaletteEntry | 一个 PAL0 颜色条目的不可变数据对象 |
BlockEntry | 一个 VFP 目录项的不可变数据对象 |
VfpError | 不支持、损坏或不一致 VFP 的异常 |
所有实例方法只读源文件。export_json()、to_vox()、extract_glb() 会写入你提供的输出路径,但不会更改打开的 VFP。公开 API 不承诺私有属性或内部函数的稳定性。
完整签名速查
class VfpReader:
@classmethod
def open(cls, path: str | pathlib.Path) -> VfpReader: ...
def inspect(self) -> dict[str, object]: ...
def manifest(self) -> dict[str, typing.Any]: ...
def palette(self) -> tuple[PaletteEntry, ...]: ...
def voxels(self) -> bytes: ...
def read_section(self, tag: str, *, chunk_id: int = -1) -> bytes: ...
def validate_source(self) -> dict[str, object]: ...
def export_json(self, output_path: str | pathlib.Path) -> dict[str, object]: ...
def to_vox(self, output_path: str | pathlib.Path) -> dict[str, object]: ...
def extract_glb(self, output_path: str | pathlib.Path) -> dict[str, object]: ...
这里的类型标注描述调用边界,不表示所有内部实现对象是公开 API。例如 BlockEntry 作为数据类型被导出,但 Reader 不提供公开的“列出每一个 BlockEntry”方法。
参数一致性规则
| 参数名 | 出现方法 | 共同语义 |
|---|---|---|
path | open、构造函数 | 输入 VFP 的本地路径;支持 str/Path |
tag | read_section | ASCII tag;推荐四字符 VFP 区段名 |
chunk_id | read_section | 关键字参数;默认 -1 表示全局区段 |
output_path | 三个导出方法 | 本地目标路径;不会自动创建父目录 |
所有 output_path 方法都可能覆盖一个已有文件。SDK 不提供 overwrite=False、mkdir=True、流式 writer 或回调参数;这些策略由调用方在调用前实现。
异常一致性规则
VfpError 表示 VFP 内容不能按 Reader 的 1.3 规则安全使用。OSError 表示输出路径、文件 stat 或底层写入环境失败。个别底层读取 OSError 在 open() 阶段会被包装为 VfpError,这是当前实现的一部分;服务层应记录调用阶段,而不是只根据异常类判断根因。
TypeError 和 UnicodeEncodeError 属于 Python 参数使用错误,例如遗漏必选参数、为 keyword-only chunk_id 使用位置参数、或向 read_section 传入无法 ASCII 编码的 tag。它们应在开发/测试阶段被修正,而不是当作用户上传格式错误。
线程与重入
公开 API 没有共享全局可变状态,每次调用使用短生命周期文件读取。不过 Reader 也没有声明并发缓存保证;最清晰的使用方式是每个任务创建自己的 Reader,并避免在另一个线程同时替换同一路径文件。
导出 API 不对同一 output_path 加锁。并发任务若写入同一目标,最后写入者获胜或产生竞争结果;上层应通过任务键、文件锁或版本化路径避免冲突。
选择 API 的决策表
| 你已经知道什么 | 你需要什么 | 首选调用 |
|---|---|---|
| 只有一个路径 | 文件是否像 VFP 1.3 | VfpReader.open() |
| Reader 已打开 | 网格、区段、缓存摘要 | inspect() |
| Reader 已打开 | META 的业务字段 | manifest() |
| Reader 已打开 | RGB 颜色定义 | palette() |
| Reader 已打开 | 全局体素占用 | voxels() |
| Reader 已打开 | 信任模型内容 | validate_source() |
| 可信 Reader | JSON 或 VOX 文件 | 对应导出方法 |
| 任何 Reader | 已嵌入的 GLB | extract_glb(),且 PRVW 必须存在 |
这张表不能替代单页参数文档,但能避免两个常见误用:将 inspect() 当作完整验证,以及将 read_section("VOX0") 当作完整体素读取。