1.6 文件格式和网络协议
在计算机应用中存在几个其他形式的常用通信"协议",其中最常见的一个就是文件格式。它是使用众所周知的数据组织层次将内存中的数据存储到磁盘文件上的方法。比如,JPEG文件交换格式(JFIF)是用来交换JPEG编码图像的图像文件格式,通常使用.jpg或.jpeg文件扩展名。表1-2展示了JFIF文件头格式。
表1-2 JFIF 文件格式头部规范
|
属性
|
字 节 数
|
描述
|
|
APP0 marker
|
2
|
总是 0xFFE0
|
|
Length
|
2
|
除APP0 marker外的片段长度
|
|
Identifier
|
5
|
总是 0x4A46494600 (“JFIF\0”)
|
|
Version
|
2
|
0x0102
|
|
Density units
|
1
|
单位像素密度属性,0表示无单位
|
|
X density
|
2
|
整型水平像素密度
|
|
Y density
|
2
|
整型垂直像素密度
|
|
Thumbnail width (w)
|
1
|
内嵌缩略图的水平大小
|
|
Thumbnail height (h)
|
1
|
内嵌缩略图的垂直大小
|
|
Thumbnail data
|
3 × w × h
|
无压缩24位RGB栅格数据
|
有了数据文件的格式,例如表1-2给出的JFIF/JPEG格式,任何程序都能读写这种格式的图像文件。这就使得不同的用户之间可以交换图像数据,从而也衍生了图像查看器和能操作这些图像的工具。
同样,客户端/服务器应用、点对点应用以及中间件服务,使用建立好的且通常基于网络套接字的协议发送和接收数据。例如,Subversion版本控制系统使用客户端/服务器结构,其中主库保存在服务器,由个人客户端实现本地客户端与服务器的同步(Rooney, 2005)。为了完成此工作,客户端和服务器就必须在网络传输中遵循相同的数据格式。这被称为客户端/服务器协议,也被称为线路协议。如果客户机发送不符合这种协议的数据流,那么服务器就无法明白此信息的含义。因此,仔细定义客户端/服务器协议的规范并确保客户端和服务器都遵循该规范是十分关键的。
这些例子在概念上都和API相似,在API中为了交换信息也需要定义标准的接口或规范。此外,任何规范的变更必定要考虑到对现有客户端的影响。虽然它们具有相似性,但文件格式和线路协议却不是真正的API,因为它们不是程序的编程(www.cppentry.com)接口,因此不能被链接到应用程序中。一个较好的经验法则是,每当你拥有一个文件格式或客户端/服务器协议时,就应该制作附属的API以管理规范变更。
提示
每当你创建一个文件格式或者客户端/服务器协议时,同时也要为其创建API。这样,规范的细节以及未来的任何变更都将是集中且隐蔽的。
例如,如果你为应用的数据指定了文件格式,那么你应该编写读写此文件格式的API。这是一种很好的做法,如此一来,我们就不必在应用程序中到处编写文件格式处理代码了。更重要的是,有了API就可以轻松改变文件格式,而不必重新编写除API实现之外的任何代码。如果你的文件格式最终存在多个不同的版本,那么API能将这种复杂性抽象出来,以便读写该格式的任意版本中的数据或判断该格式是否是由新版API所编写,进而采用恰当的处理方式。从本质上说,就是隐藏了磁盘上数据的真实格式的实现细节,使应用程序不必关心它们。
这个建议也同样适用于客户端/服务器应用,在定义了公共协议和管理公共协议的公共API后,客户端团队和服务器团队彼此之间就能相对独立地工作了。例如,你可能在刚开始的时候用UDP作为系统传输层的一部分,但是随后决定改用TCP(Second Life的代码就是这样)。如果所有的网络访问都抽象到一个适当的API中,那么这种巨大的实现变更将不会对系统其他部分造成破坏性影响。