\title{文件格式的演进与设计思路}
\author{黄京}
\date{Aug 21, 2026}
\maketitle
日常使用电脑或移动设备时，人们常常会遇到这样的场景：多年以前用旧版 PowerPoint 制作的演示文稿无法在新机器上正常打开；将一台 Windows 电脑上的三维模型复制到 Mac 后，渲染软件却提示「文件损坏」；把手机拍摄的照片上传到云盘后，另一台设备下载下来却发现 EXIF 信息丢失。所有这些问题的根源，都可以追溯到「文件格式」这一看似透明却至关重要的技术规范。格式并非简单的后缀名，而是数据、规则与生态三者的集合体。它决定了字节如何被解释、结构如何被遍历、元数据如何被附加，并最终决定了软件能否在不同平台、不同版本间实现互操作。\par
在工程实践中，格式的三个要素常常被分别讨论。编码决定了信息如何映射为字节序列，例如 UTF-8、IEEE 754 浮点数或变长整数 Varint。结构则定义了字节流内部的布局，例如 TIFF 的 Image File Directory、PDF 的交叉引用表或 Parquet 的 Footer。元数据负责描述数据本身的属性，例如 MIME 类型、Magic Number、版本字段或校验和。当这三者配合得当，格式就具备了可读、可写、可演进的特性；反之，哪怕只在其中一环出现歧义，都可能导致整个生态的碎片化。\par
本文将沿着历史脉络展开，先回顾物理介质到云原生的演进路径，再横向对比同类场景的不同设计思路，随后拆解可复用的设计原则，最后以失败案例与未来趋势收尾。读者可将本文视为一次关于「数字纸张」的系统性考察，理解格式如何塑造软件世界，又如何被软件世界反向塑造。\par
\chapter{纵向演进：从物理介质到云原生}
\section{早期：固定长度记录与顺序存取}
在电子计算的黎明时期，数据持久化主要依赖打孔卡与磁带。IBM 80 列卡片以列为单位，每列可打 12 个孔位，共同编码一个字符。字符集通常采用 EBCDIC，这一编码在今天看来已显笨重，却在当时为金融与政务系统提供了统一的数据交换语言。磁带则采用块寻址方式，每块长度固定，块间以空白间隔分隔。顺序存取意味着若要读取第 N 条记录，必须先跳过前 N-1 条；这在批处理时代并不构成瓶颈，却为后来的随机访问需求埋下了伏笔。理解这一阶段的格式特征，有助于我们意识到「固定长度」与「顺序」曾是性能优化的默认选项，而非今日语境下的技术债务。\par
\section{桌面时代：二进制容器与富文本}
个人电脑普及后，字处理与表格软件成为主流。微软的 .doc 与 .xls 采用 OLE 复合文件格式，本质是一个小型文件系统，内含多个「流」与「存储」，分别对应文档正文、样式表、宏代码等。TIFF 则通过 Image File Directory 组织多页扫描图像，每个 IFD 由一系列 12 字节的 Tag 构成，Tag 可指向私有数据区，从而允许厂商扩展功能。值得注意的是，.docx 的向后兼容性并非源于格式本身的超前设计，而是源于 ZIP 容器 + XML 文本的组合：旧解析器遇到未知命名空间可直接忽略，新解析器则可按需读取。这种「可忽略块」的思路后来被 PNG、PDF 等格式反复借鉴。\par
\section{互联网时代：文本化与结构化}
HTTP 与万维网的兴起，迫使格式向「人类可读」妥协。HTML、XML、JSON 相继成为事实标准，它们将结构信息直接嵌入文本，极大降低了调试与审计成本。PDF 则代表另一种思路：它把页面描述语言 PostScript 的核心指令封装为二进制对象，通过交叉引用表实现随机访问，最终实现了「一次编写、到处运行」的跨平台目标。音视频领域，ISO-BMFF（即 MP4 的基础）统一了此前 QuickTime、MPEG-2 TS 等相互竞争的容器格式，其 Box 结构允许在文件尾部追加新类型的数据，而无需改动已有解析逻辑。\par
\section{云原生：对象存储与增量更新}
当存储从本地磁盘迁移到对象存储，访问模式从「一次加载整个文件」转向「按需读取字节范围」。Parquet 与 ORC 正是为这一场景而生：它们将数据按列组织，每个列块内部再按 Page 细分，Footer 中记录了每个 Page 的偏移与统计信息，从而支持在不解压全文的前提下完成谓词下推。Protocol Buffers 与 FlatBuffers 则把序列化与反序列化之间的内存拷贝降至零，前者通过 Varint 与 ZigZag 编码实现紧凑表示，后者则通过直接内存映射实现零拷贝。Figma 与 Google Docs 的协作模型进一步引入 CRDT，使得文件不再是静态的字节快照，而是可在并发编辑下自动合并的增量日志。这些演进共同指向一个方向：格式不再只是「如何存储」，而是「如何在分布式环境下持续演进」。\par
\chapter{横向比较：同类场景的不同解法}
矢量图形领域，SVG 以 XML 文本承载路径与样式，具备脚本可读性，却牺牲了体积；Adobe Illustrator 的 .AI 则在 PDF 基础上叠加私有数据，兼顾了编辑性与兼容性，但也造成了闭源的复杂性。3D 模型方面，glTF 以 JSON 描述场景图，结合二进制 BufferView，面向实时渲染做了极致优化；FBX 则保留了完整的影视管线元数据，体积更大但信息更全；USD 试图在二者之间寻找平衡，通过分层组合与时间采样支持工业级协作。文档协作场景，.docx 与 .odt 均采用 ZIP+XML，却在命名空间与关系图上存在差异；Apple 的 .pages 则使用自定义序列化，牺牲了互操作性。科学数据领域，HDF5 以单一文件管理多维数组与元数据，适合大规模并行读写；Zarr 将数据切分为目录树中的块文件，更适合对象存储；FITS 则沿用固定长度记录，面向天文归档做了极致简化。这些案例表明，同一场景下，不同格式的取舍本质上是「可编辑性、体积、兼容性、安全性」四者间的权衡。\par
\chapter{核心设计思路拆解}
\section{分层抽象}
任何格式都可分解为物理层、逻辑层与语义层。物理层关注字节序与编码，例如大端与小端的转换、Varint 的高位延续标志、ZigZag 的符号映射。逻辑层负责索引结构，例如 TIFF 的 IFD 链表、PDF 的交叉引用表、Parquet 的 Footer。语义层则通过 MIME、Magic Number 与版本字段，告诉解析器「这是什么、该用哪个解析器、该用哪个版本的规则」。三层之间通过清晰的接口隔离，使得上层逻辑可以在不感知物理细节的前提下完成演进。\par
\section{向前/向后兼容策略}
向前兼容意味着旧解析器遇到新格式仍能部分工作，向后兼容则意味着新解析器能读取旧文件。Protobuf 通过保留字段编号实现：未被识别的字段被跳过，但不会导致解析失败。PNG 的 ancillary chunks 允许解析器在不理解块类型时直接忽略。PDF 的 incremental update 则把新版本的修改追加到文件尾部，同时更新交叉引用表，旧解析器仍可读取旧版本页面。TLS 的密码套件协商机制同样体现了这一思路：双方在握手阶段选出共同支持的算法，从而在不破坏既有部署的前提下引入新算法。\par
\section{压缩与随机访问的平衡}
整块压缩（如 ZIP 的 Deflate）能获得较高压缩率，却要求解压全文才能访问任意位置。Parquet 的 Page 级压缩则把文件切分为多个独立压缩单元，每个 Page 内部可随机访问，同时保留了列式存储的向量化优势。Avro 通过在文件头放置共享字典，把重复字符串的存储开销降至一次，后续引用仅需整数索引。设计者需要在「压缩率」与「随机访问延迟」之间寻找最优解，而非一味追求极致压缩。\par
\section{安全性与可扩展性}
PDF 的 JavaScript 与 Office 宏曾被多次用于投递恶意代码，根源在于格式允许嵌入可执行内容却缺乏有效沙箱。现代格式开始引入数字签名与 Merkle 树：Android 的 APK 通过 v2/v3 签名保护整个文件，OCI 镜像则用内容可寻址的层实现防篡改。安全不再是事后补丁，而是格式设计阶段必须回答的问题。\par
\section{工具链与生态}
单一实现的格式往往面临「作者离世即死亡」的风险。PDF、PNG 等格式的成功，很大程度上得益于多方参考实现的并存。格式检测器如 file 与 Apache Tika，通过 Magic Number 与结构特征自动识别文件类型，进一步降低了生态碎片化成本。设计者应在发布格式的同时，提供最小可行解析器示例，并明确许可证，以降低第三方实现门槛。\par
\chapter{典型失败与教训}
Flash 的 .swf 格式因封闭规范与安全漏洞双重因素，最终被 HTML5 Canvas 与 WebGL 取代。QuickTime 的 .mov 因多索引版本混乱，导致解析器需要处理数十种变体，最终被 MP4 统一。早期 CAD 的 .dwg 因私有二进制格式，开源替代长期受阻。这些失败案例共同指向一个教训：封闭与过度复杂是格式死亡的加速器，而开放、清晰、工具链友好的格式更可能长期存活。\par
\chapter{设计 checklist}
在设计新格式时，可逐一审视以下问题：是否必须二进制，文本 JSON 是否足够？是否需要流式读写？版本演进路径是否清晰？是否提供最小可行解析器示例？压缩算法的许可证是否友好？是否考虑跨平台字节序与时间精度？这些问题看似琐碎，却往往决定格式能否在真实世界中落地。\par
\chapter{未来展望}
Wasm 的普及使得「可执行格式」成为可能：格式本身可携带轻量级解码逻辑，解析器只需提供运行时环境。AI 模型权重格式如 Safetensors 与 GGUF，通过显式张量描述与零拷贝映射，解决了 PyTorch Pickle 的安全隐患。持久化内存（PMEM）与内存映射的结合，让文件与内存的界限进一步模糊。星际文件系统（IPFS）则把内容寻址推向极致：文件名不再是字符串，而是内容的哈希值，格式演进从「位置」转向「内容」。\par
文件格式是数字时代的纸张。它既是约束，也是扩展性的载体。好的格式在提供明确规则的同时，留出足够的演进空间；它鼓励多方实现，拥抱工具链友好，并在安全与性能之间持续寻找平衡。希望读者在设计下一代数据载体时，优先考虑开放、可演进、工具链友好这三条原则，让数据在时间与空间中自由流动，而非被格式的藩篱所困。\par
