从体系结构上看,Mac OS X实现了对多文件系统的支持,其中最为重要的文件系统包括有:Mac OS Extended (HFS+),Mac OS Standard (HFS),UFS, ISO 9660, NFS和 AFP。但从用户的角度看,文件系统又是单一的。当用户复制,移动或拖移文件和文件夹时,(会感觉似乎)只存在一个文件系统。
本章从两种角度审视了文件系统并谈论了一些对于软件开发人员有意义的话题。首先它描述了Mac OS X中标准的目录分层,即Mac OS X系统中应用程序,文档,框架和资源放在一个多用户,网络化的计算机环境中。随后还讲述了在各种文件系统之间,特别是在占主导地位的HFS+ 和UFS系统之间,相互操作的区别以及产生的问题。它还解释了HFS资源分支的实现及与此实现相关的策略。
Mac OS X文件系统中的几乎每个文件都有其适合放置的存储这一类型文件的标准目录区域。而对用户来说,这并不意味着他们就必须把应用程序和应用程序资源放在被推荐的区域。由于应用程序最终会被打包,因此无论他们被安装在哪里,都能满足自身要求。但假如用户没有把某些内容放在系统软件期望的位置。他们有可能会丧失Mac OS X的一些优势。例如,Finder首先通过搜索应用程序的标准位置来导入应用程序数据库(见“收集应用程序信息”一节)。一旦这样做,结果有可能会造成一个隶属于某个应用程序(但不在那一区域)的文档,不能在双击时被立即打开。
在探究文件系统组织的基本原理之前,首先思考一下文件系统的顶层究竟显示了些什么。列表9-1举例说明了一个假定的安装状况。
列表 9-1 Mac OS X文件系统顶层的样例
/Mac OS X/
/Network/
/OtherVolumes/文件系统的层次通常被表现为一个以“根(root)”开始的分层结构,在典型的Mac OS X文件系统的根目录中(“根”用起始的“/”符号来表示),它包含以下项目:
- /Mac OS X/--一个特殊的卷,操作系统由它开始启动,系统文件和资源也被安装在其上。这个卷通常是一个被格式为Mac OS扩展格式(HFS+,Mac OS Extended)的卷(虽然它也可以是UFS卷)。名称“Mac OS X”是它默认的卷名,但用户也可以修改它。
- /Network/--作为装载到用户系统上的本地网络的根目录。无论用户是否连接到网络上,/Network/目录(其图标是一个“地球”)将始终出现。
- /OtherVolumes/--显示一个或多个被连接的外部设备或不是启动卷的内部设备。其中可以包括有Zip驱动器,CD-ROM驱动器,数码相机,被装载的网络服务器以及硬盘和它们的分区等。(“OtherVolumes”只是一个真实名称的代表,被连接的卷的实际名称将会是不同的)。
所有非启动卷在它们被装载时出现,被卸载时消失。对此有一个例外,用户的iDisk卷即使在被卸载后也不会消失。
卷的物理结构与Finder向用户所显示的略有不同。假如用Terminal程序看一下目录结构,您会看到启动卷被装载在根目录层(/),而非启动卷被放在/Volumes/目录中。Finder提供了这种抽象方式,用来在基本的UNIX 系统上提供一个更加传统的Mac OS界面。
像/usr, /bin和/etc等目录都是标准的BSD目录,它们也存在于根目录层,但Finder向用户隐藏了它们。
在一个控制访问系统资源的多用户系统中,保持系统的稳定性是非常重要的。Mac OS X定义了几个文件系统域,每个域在一组确定的目录中提供了资源的存储。在每个域中对资源的访问由当前用户的权限决定。
有四种文件系统域,在以下列表中描述了每一种域:
- 用户:用户域包含了登入系统用户的特定资源。这个域由用户的home目录来定义,它可以是在启动卷(/Mac OS X/)上,也可以是在网络上。用户完全控制了这个域中的一切。
- 本地:本地域包含了由一个特定系统上所有用户所共享的应用程序和文档等资源,其不要求由系统来运行。本地域并不对应某个单独的物理目录,而是由几个本地启动(和root)卷上的目录组成。拥有系统管理员权限的用户可以增加,删除和移动这个域中的项目。
- 网络:网络域包含了由一个本地网络上所有用户所共享的应用程序和文档等资源。这个域中的项目通常放在网络文件服务器上,并由网络管理员控制。
- 系统:系统域包含了由Apple安装的系统软件。系统域中的资源要求由系统来运行。这个域中的项目被放在本地的启动(和root)卷上。用户不可以增加,删除或是修改这个域中的项目。
特定资源的域决定了其对系统中用户的适用性和可存取性。举个例子来说,一个安装在用户home目录中的字库只有对那个用户可用。如果一个管理员将同一个字库安在网络域,那么所有的网络用户都将能访问它。
Mac OS X在每个域中提供了一套基本目录来组织被包含的资源。Mac OS X在不同的域中都使用相同的目录名来存储相同类型的资源。这种一致性简化了查找用户和系统使用资源的过程,当用系统需要寻找一个资源时,它会按顺序搜索各个域,直到找到这个资源。搜索从用户域开始,然后依次在本地,网络和系统域中进行搜索。
您的程序代码不应假定一个文件系统域中资源的路径,因为这些路径将来可能会被修改。Apple提供了访问标准文件系统路径的公共API。通常情况下您应该使用这些API来定位您的文件资源。关于搜索域中项目的更多信息,请参见“搜索文件系统域”一章。
以下章节更详细的描述了每个文件系统域,包括那些域中提供的标准目录。
用户域包含了一个单独用户的特定资源。用户域由当前(已登入)用户的home目录来表示。 Mac OS X计算机上的每个用户必须在那台机器或它所连接的本地网络上有一个帐户。每个用户帐号在文件系统中都有一块分配的空间,称为用户home目录。这个目录就是用户程序,资源和文档存放的地方。每个用户的home目录名称都是基于用户的短登入名,它必须是唯一的。
用户域使每个用户能够定制各自的工作环境。当一个用户登入时,Finder会使用用户域中的预置来还原用户的工作环境和针对以前状态的设定。同样,程序和其他系统软件也会使用用户域中的信息来恢复应用程序设置,网络设置,邮件设置,字体设置,ColorSync描述和其他设置。
用户home目录的位置--用户域--是由用户帐号来决定的。如果是计算机的本地用户帐号,用户home目录存在于启动卷的Users目录中。如果是一个网络用户帐号,其home目录是在一个网络服务器上。不用考虑home目录的物理位置,在一些情况下Mac OS X根据UNIX中的习惯,使用“~”符号(代字符)来指明一个用户的home目录。“~”符号(代字符)可以用于连接其他目录或用户名称,来说明特定的用户目录。表9-1说明了这一概念。
图9-1 使用代字符来说明home目录中的位置
~ 当前用户home目录的顶层 ~/Library/Fonts 当前用户home目录中存储字体的位置 ~Steve 用户Steve的home目录的顶层 在每个新用户的home目录中适当的位置上,都存在一些缺省的子目录和资源。用户home目录中的这些子目录映射着在iDisk帐户中所能找到的内容。(关于iDisk的更多信息,请参见http://www.apple.com.上iTools部分)。对于用户home目录中的缺省子目录而言,同样不用考虑home目录是在哪里被创建的。表9-2列出了用户home目录的标准子目录。
表9-2 默认home目录的内容
用户 目录描述Desktopc 包含了Finder在登入用户桌面上所显示的项目 Documents 包含了用户的个人文档 Library 包含了特定用户的应用程序的设置,预置和其他系统资源。请参见“Library 目录”一章。 Movies 包含了QuickTime和其他格式的数字电影 Music 包含了数字音乐文件(.aiff,.mp3和其它格式) Pictures 包含了各种格式的图像 Public 包含了用户希望与其他用户共享的项目,默认时,这个目录对其他用户是可访问的。 Sites 包含了用户的个人web站点中的web页面。Web Sharing必须在这些页面被其他用户访问前被激活。 当一个用户帐号被创建时,Applications目录不会自动被加到用户home目录中。然而用户可以自己创建一个Applications目录,并将他们自己的应用程序放在其中。系统会自动在这个位置搜索应用程序。
系统通过一组默认权限来保护用户home目录中的文件和目录,以避免外界的干扰,用户也可以随时改变这些权限。用户所创建的任何新的文件夹都会继承其父目录的权限。
除了个人用户的home目录外,Users目录还包含了一个Shared共享子目录。这个目录可以被本地机算机系统上的任何用户访问。任何用户都可以在这个目录中写入文档,从中检索文档和读取文档。虽然这个目录并没有真正与用户域联系起来,但它为用户交换文档和其他文件提供了便利的方法。
本地域包含了在本地计算机上可用的资源,但它不要求由系统来运行。本地域中的资源通常包含应用程序,实用工具,用户字体和用户启动选项及全局应用程序的设置。启动卷上的Applications应用程序目录和Library库目录包含了本地域中的资源。这些资源对于当前计算机系统上的用户是可用的,但对于其他网络计算机上的用户是不可用的。
如果希望资源能够被系统中所有的用户所共享,计算机管理员可以将这些资源安装到本地域中。Apple将其应用程序装在/Applications 和/Applications/Utilities 目录下。第三方应用程序和实用工具也应该放置在这些目录中。其他系统资源,例如字体库,ColorSync描述,预置和插件则应该放置在Library目录中的适当的子目录中。关于Library目录的更多信息,请参见“Library 目录”一节。
网络域包含了对于本地网络的所有用户可用的资源。网络用户可以通过这个域来访问应用程序,文档和其他资源,其包括了AppleShare和Web服务器。网络域确切的组成取决于所采用的协同策略,网络管理员负责网络域的实现。
表9-3列出了在网络域中所提供的标准目录,以及对各个目录内容的描述。
表9-3网络目录
位置 描述/Network/Applications 包含了本地网络上所有用户都可以运行的应用程序。 /Network/Library 包含了本地网络上所有用户都可用的资源,如插件,声音文件,文档,框架,颜色和字体等。关于Library目录的更多信息,请参见“Library 目录”一节。 /Network/Servers 包含了组成本地网络的NFS文件服务器的装载点 /Network/Users/ 包含了所有本地网络用户的home文件夹。这是home文件夹的默认位置。用户的home文件夹还可以存放在其他的服务器上。
系统域包含了要求由Mac OS X来运行的资源。系统域中的所有资源被放置在启动卷上的/System目录下。这些资源由Apple提供,只有root用户可以修改这个目录的内容。管理用户和应用程序不能在系统域中安装资源或是直接修改它的内容。
默认情况下,/System目录仅包含了一个Library子目录。与系统中的其他Library目录一样,这个子目录中包含了许多相同类型的资源。然而在系统域中,这个目录还包含了构成Mac OS X系统的许多核心服务,框架和应用户程序。关于Library目录的更多信息,请参见“Library 目录”一节。
虽然Classic兼容环境包含了系统相关的资源,但其不被作为系统域的一部分。关于Classic更多信息,请参见“Classic环境目录”一章节。
Library是一个特殊的目录,用于存储特定的应用程序和特定的系统资源。每个文件系统域都有其自身Library目录的副本,这些Library目录具有不同的访问级别以匹配不同的域类型。虽然一个应用程序可以使用这个目录来存储内部数据或临时文件,但将应用程序的束自身或是用户数据文件存放在Library目录中将是不足取的。应用程序的束应放在一个/Applications目录中,而用户数据应放在用户的home目录中。
Library包含了许多标准的子目录。系统例程要求许多标准子目录必须存在,因此删除Library的子目录决不是一个好主意。然而,当需要存储特定的应用程序数据时,应用程序可以创建一个新的子目录。
表9-4列出了在Library目录中所出现的一些目录。这个列表是不完全的,但它列出与开发人员相关的大部分目录。没有出现在所有域中的目录会被适当地说明。
表9-4 /Library目录的子目录
子目录 目录内容Application Support 特定应用程序的第三方插件,帮助程序,模板和其他资源。按规定,这些项目应被放置在以应用程序命名的子目录中。举个列子,应用程序MyApp的第三方资源将被放在Application Support/MyApp/中。注意,一个由应用程序开发者创建的资源应被放置在自己的应用程序包中。更多信息请参见“应用程序包”一章节。 Assistants 帮助用户完成配置和其它任务的程序。 Audio 声音插件和设备驱动。 ColorPickers 根据某一模式取色的资源,例如HLS (Hue Angle, Saturation, Lightness) 取色器或RGB 取色器。 ColorSync ColorSync描述和脚本 Components 系统中的插件和扩展。 Documentation 文档文件和Apple 的帮助包(在子目录Help中),计算机上的用户和管理员可以使用它们。在本地域中,这个目录包含了Apple安装的帮助包(包括开发者文档)。 Extensions 设备驱动和其他内部扩展(仅为系统域)。 Favorites 时常被访问的文件夹,文件或Web站点的替身(仅为用户域)。 Fonts 用于显示和打印的字体文件。 Frameworks 框架和共享库。 Internet 用于Internet的插件,库和过滤器。 Keyboards 键盘定义。 包含了用户的邮箱(仅为用户域)。 Preferences 用户预置,请参见“系统预置”一章中的“用户配置”一节。 Printers 打印驱动(由厂商提供)和PPD插件。 QuickTime QuickTime的插件和扩展。 Scripting Additions 扩充了AppleScript功能的脚本及脚本资源。 Sherlock Plug-ins 扩充了Sherlock功能的插件。 Sounds 系统警告声。 StartupItems 在启动时运行的系统及第三方的脚本和程序,更多信息请参见“引导和登入”一章中“启动项目”一节。 Web Server Web 服务器的内容,这个目录包含了CGI脚本以及所备置的Web页面。
用于开发Mac OS X软件的应用程序,工具,文档及其他资源是一个可选的软件安装包。当您安装开发工具时,安装程序会把所有软件组件放到位于启动卷(/Mac OS X)的Developer目录中。
表9-5 显示了Developer目录的内容。
表9-5 Developer目录内容
目录 内容Applications 用户管理和建立软件项目(Project Builder),创建用户界面(Interface Builder)和执行调试程序的应用程序。 Documentation 开发者文档 Examples 分类组织的项目实例(Carbon,Java等等)。 Headers 特殊的头文件,诸如:遗留的简单 Carbon头文件。 Java 在Cocoa应用程序环境中用于Java桥接所需的文件。 Makefiles 用于建立和改变项目所需的makefile(.make文件)和jamfile(.jam文件)。 Palettes Apple 提供的Interface Builder的调色板。 PBBundles Project Builder使用的可装载的束。 ProjectBuilder Extras Project Builder的模板和插件。 ProjectTypes Project Builder使用的项目类型的定义 Tools 命令行开发工具,包括那些创建和生成HFS资源分支的工具。 Project Builder定义了一组makefile变量,当您的项目在文件系统域中指定位置时,应该会使用到它们。您应该使用这些变量而不是将目录路径硬编码,因为这些位置可能会被改变。
关于创建设置(包含makefile变量)的完整列表,请参见Project Builder 帮助。
Classic环境包含了几个用于支持Classic应用程序的目录。这些Classic环境下的目录是一个Mac OS 9安装版本中的目录。Mac OS X 需要为Classic环境安装一个 Mac OS 9.1(或更新的版本)。如果一个系统安装了一个比Mac OS 9更早的版本,用户必须安装一个更新的版本来支持Mac OS X。
一个系统可能有多个Mac OS 9版本安装在不同的分区上。如果是这种情况,系统预置的Classic设置面板将让用户为Classic环境选择使用其中的一个Mac OS 9版本。用户第一次启动Classic时,系统会将一些必要的文件附加到被选取的Mac OS 9卷的系统文件夹内。您也可以使用系统预置中的Classic设置面板随时启动或停止Classic运行环境。用户还可以使用“启动磁盘(Startup Disk)”系统预置来改变启动磁盘,以从Mac OS X变为直接启动进入Mac OS 9。
当您在一个卷上安装了Mac OS 9.1(或更新的版本)时,安装程序会创建几个目录来存储系统文件。表9-6列出了安装程序创建的目录以及关于其内容的描述。如果您已经安装了一个Mac OS X 和 Mac OS 9.1(或更新)的本版,Mac OS 9 的安装程序可能不会创建所有这些目录。
表9-6 Mac OS 9.1(或更新的版本)的安装程序创建的目录。
目录 描述Applications (Mac OS 9) 包含了Mac OS 9(Classic)的应用程序和实用工具。 Documents 包含了特定应用程序的信息。这个目录只能由Classic应用程序使用。Mac OS X应用程序会在适当的/Library目录中存储预置和其他应用程序文件。用户应该把他们的文档存放在他们自己的home目录当中。 System Folder 包含了Classic环境的系统文件。 当您在一个已经装有Mac OS 9的系统上安装Mac OS X时,安装程序会执行一些额外的任务来支持Classic环境。尤其Mac OS X安装程序会创建一个Mac OS 9桌面文件夹的替身,并把它放在可以运行安装程序的管理员用户的桌面上。这个替身包含了在Mac OS X 安装之前Mac OS 9桌面上任何文件的链接。
Mac OS X包括了二个公共的可编程接口,您可以用其来搜索特定(或所有)域中特定目录位置中的资源,插件和其他项目。这两个API其中之一是--Folder Manager(文件夹管理器)的FindFolder函数--是为Carbon程序提供的。另一个API--在System framework(系统框架) 的NSPathUtilities.h中定义的函数和常量--是为任何其他类型程序提供的。
这两个API帮助您搜索所有文件系统域中某个特别的项目。按规定,搜索通常从最特定域开始并结束于最通用的域。搜索域的顺序如下:
1.用户
2.本地
3.网络
4.系统大多数系统软件在所有文件系统域中搜索项目时按照这个顺序。然而,您也可以按适合您应用程序需要的任何顺序来搜索。
在Mac OS X中,文件的类型可以分别用两种方法来识别:文件类型编码和文件扩展名。文件类型编码在Mac OS 9中普遍使用,其作为文件元数据存储。文件扩展名通常在Windows 和 UNIX操作系统上使用,Mac OS X对其支持是为了提供与其他操作系统更高的兼容性。然而为了保持Macintosh用户的操作体验,Mac OS X在每个文件的基础上提供了一种隐藏扩展名的方法。
现今文件系统中的每个文件都有一个特殊的标记来标识文件是否被隐藏或是显示。这一设置仅仅影响了文件显示的方式,但不会实际改变文件系统中的文件名。用户可以在文件的Info面板中为各个文件改变这一设置。用户还可以通过修改Finder的预置来隐藏所有文件扩展名。
应用程序显示文件名作为用户界面的一部分时必须使用特殊例程来得到一个文件的显示名称。当NSFileManager 调用displayNameAtPath 返回一个文件名时,Launch Services使用LSCopyDisplayNameForRef和LSCopyDisplayNameForURL方法来识别文件扩展名标记。您的应用程序只有在用户界面中显示文件时才会使用这些方法。您的应用程序生成的任何其他内部文件通常使用文件全名。
当打开,保存文件时,应用程序还需注意文件扩展名隐藏预置,包括以下内容:
- 保存对话框应该允许用户控制是否隐藏文件扩展名。
- 当打开或保存一个文档时,应用程序应保持已有show/hide(显示/隐藏)设置以及文件扩展名。
- 当用Save As命令保存已有的文件或一个新的文件时,应用程序应该加入适当的扩展名。
- 应用程序不应添加扩展名或改变一个没有扩展名文件的show/hide(显示/隐藏)设置。
Carbon 和Cocoa都允许文件扩展名在相应的Save对话框中隐藏。在Carbon中, 您可以为Navigation Services对话框设置kNavPreserveSaveFileExtension对话框选项。对Cocoa来说,您可以使用setCanSelectHiddenExtension(NSSavePanel的方法)来允许这一特性。更多信息请参阅“Carbon 和 Cocoa预置”一章。
Mac OS X支持多个选定的文件系统组件同时本地化。文件系统组件的本地化支持是为了提供用户一个比他们以前得到的更为完整的本地化服务。先前,当用户改变系统的语言设置时,菜单栏和UI(用户界面)组件会随之改变,而文件系统组件如:文件系统名,则会保持原来的默认名称。而现在,选定的文件系统名也会改变成当前选择的语言。这使得用户可以用他们的母语来浏览更多的文件系统层。
Mac OS X提供了主要针对系统文件夹和束名称的本地化支持,包括应用程序名。目录名称如:System,Applications, Library等,如今都可以以登入用户当前选择的语言来显示了。关于本地化应用程序名的更多信息,请参见“本地化束名”一章节。关于本地化目录名的更多信息,请参见“本地化目录名”一章节。文件扩展名决不会被本地化。
注意
Mac OS X在Darwin 和Classic环境中不支持本地化束名和目录名,Mac OS X也不支持本地化平文件。
开发人员需在他们的应用程序中注意本地化的文件系统名,并适当的显示他们。本地化路径只是为了通过您应用程序的用户界面来向用户显示。您决不要试图用本地化文件路径名来直接访问文件,也不要在您的预置文件或内部缓存存储本地化文件路径。通常只有在向用户显示一个路径前才会本地化该路径名。
Mac OS X提供了几个函数来获取路径的本地化名称。在显示一个路径前,您的应用程序通常应使用这些函数将它转换成本地化名称。除了本地化适当目录和束名外,这些方法被当前文件和Finder设置调用时会隐藏文件扩展名。当NSFileManager 调用displayNameAtPath 方法时,Launch Services使用LSCopyDisplayNameForRef 和 LSCopyDisplayNameForURL将路径转换成本地化格式。
束和应用程序通过已有的束本地化机制来支持本地化文件名。束的Resources文件夹可以包含多个.lproj子目录,每个目录包含了一种语言的本地化资源。您可以在这些语言子目录中放入的文件之一是InfoPlist.strings文件,它为特等关键字存储了本地化值。要为您的束指定一个本地化名称,这个文件中要包括CFBundleDisplayName关键字,并将其值设置为这个束的本地化名称。
在决定何时显示束的本地化名时,Mac OS X会更优先考虑用户定制的名称,而不是存储在束中默认或本地化的名称。束的Contents目录中Info.plist文件包含了CFBundleDisplayName关键字,它的值是束的显示名称。如果此关键字的值与文件系统中的束名不匹配,那么Mac OS X会使用文件系统名作为其显示名称。如果匹配,Mac OS X会使用适当的本地化名称(如果存在的话),否则就使用默认名称。
支持本地化束名的规则适用于所有的束,包括应用程序和框架。关于束的更多信息,请参见“束”一章。
如果您的应用程序包安装了任何用户支持的目录,那么您不但可以为应用程序提供本地化名称,而且也可以为这些目录提供本地化名称。本地化您特定的应用程序目录名是不必要的,而且可能并不是所有情况下都是有效的。如果您想本地化您的应用程序支持的目录,您应该仅为那些您应用程序预先知晓其名称的目录进行本地化。不建议本地化“用户特定”的目录名。
要本地化目录名,您必须为目录名加上.localized扩展并将其默认设置为隐藏。然后在您的目录中再创建一个名为.localized的子目录。在这个子目录中,为您想支持的每个本地化版本创建一个strings文件。strings文件包含了目录名的本地化版本的单一入口。举个例子,一个用English,,Japanese和 German本地化的Release Notes目录将包含以下结构
Release Notes.localized/ .localized/ en.strings de.strings ja.strings在每个strings文件当中,您要把非本地化目录名转变成本地化目录名。举个例子,要转换目录名“Release Notes”成为一个本地化目录名,每个strings文件都要包含类似以下的条目。
"Release Notes" = "Localized name"
注意:许多系统定义的目录在他们的名称里并不包含.localized扩展名。因为这些目录在引入本地化文件系统名之前已经存在。对于这些已知的目录,Mac OS X转而在目录中查找名为.localized的空文件。如果此文件存在,那Mac OS X就会显示其本地化目录名文本。
在Mac OS X的两种主要文件系统:HFS+和UFS上,有着许多重要的不同点。在许多情况下,这些不同会与在Mac OS X上开发的程序有关联。以下列表总结了在这两个文件系统中的主要不同点(有些陈述既适用于HFS又适用于HFS+):
- 大小写敏感:UFS对大小写是敏感的,而HFS+对大小写不敏感,但它可以保留大小写。
- 多分支:HFS+支持多分支(和附加的元数据)而UFS只支持单一分支(Carbon在不支持多分支的系统“如:UFS”上模似多分支结构)。
- 路径分隔符:HFS+使用冒号作为路径分隔符,而UFS中使用的则是正斜杠。系统能够在这些分隔符间进行转换。
- 修改日期:HFS+支持对文件的创建和修改日期的记录,它们将作为文件元数据被保存;而UFS只支持对文件修改日期的记录,不支持对文件创建日期的记录。如果您用一条命令来复制一个文件,这条命令将会处理修改日期,但不会处理创建日期,当它为一个副本创建一个新的文件时,这条命令将会重设其修改日期。由于这一原因,很可能会使一个文件的创建日期要比其修改日期更晚。
- Sparse文件和零填充:UFS支持sparse文件(稀疏文件),它是一种文件系统存储文件数据的方法,其不存储分配给文件的未被使用的空间。HFS+不支持sparse文件,事实上可以用"零"为文件填充所有未使用的字节直到文件结束。
- 对文件系统项目的轻量级引用:请见“替身和符号连接”一节。
另外,那些已往与每种文件系统相关联的API有时会具有不同的特性。举个例子,一个使用了BSD (或来源于BSD)API的程序可以删除一个打开着的文件;而另一方面,一个Carbon程序只可以删除一个已关闭的文件。
替身和符号连接是对文件夹和目录的轻量级引用。替身与Mac OS标准格式(HFS)和Mac OS 扩展格式(HFS+)相关联,而符号连接是UFS文件系统的一个特征。替身和符号连接都允许对文件夹和目录多次引用,而不需要为这些项目建立多份副本。Mac OS X 10.2之前,当移动或改变一个被引用的文件或文件夹时,替身和符号连接在处理方式上会有很大不同。
原先,替身首先用文件夹和目录的唯一标识来定位他们,其次才是用他们的路径。如果您在同一个卷上移动一个文件,任何指向那个文件的替身仍会指向原本那个位置。假如您删除某个文件,并用一个同名的文件代替它,替身仍可以工作,因为他们可以用路径来定位文件。而从Mac OS X 10.2起,替身颠倒了其搜索顺序,先使用路径后使用文件标识。
因为替身和符号连接都使用一个文件系统路径来断定文件位置,因此他们都提供了类似的基本工作方式。如果您用一个同名文件替换某个文件,把旧文件移到新的位置上,替身和符号连接都将指向新的文件。然而,如果您移动某个文件而不是替换它,符号连接会产生文件中断,但替身则不会。
在HFS 和HFS+文件系统中,每个文件和目录都会具有一个唯一的固定标识。替身存储了这个唯一标识以及文件或目录的路径信息。如果不能通过替身中的路径信息来找到文件,替身则会试图使用其唯一标识来定位文件。如果找到了文件,替身会用新的路径信息更新其内部记录。同样,如果路径正确,而唯一标识有错误,替身也会用新文件唯一标识来更新其内部记录。
如今Finder和其他系统应用程序用先查找路径的方式来使用替身。然而,通过使用Alias Manager(替身管理器)的方法来处置替身时,将仍会使用先根据文件唯一标识来查找的方式。
如果您的应用程序支持Mac OS X 10.2以前的Mac OS X 版本,则当您修改文件时应该遵守某些准则。首先,当需要编辑文件时,可修改已有的文件。其次,如果您明显需要用一个新版本来替换某个文件,可用FSExchangeObjects来将旧的文件替换成新的。NSDocument类用一种类似的方法来更新文档文件。因此,无论何时替身都能保持有效。
在Mac OS X和Carbon之前,应用程序资源被存放在一个应用程序可执行文件的资源分支内,这种策略如今已被改变了。通常在Mac OS X中或对Carbon应用程序来说,资源被存放在一个独立资源文件的数据分支当中,而不是可执行文件的资源分支中。
如今Carbon的API在读取和处理资源文件的数据分支中的资源时,就如同在资源分支中一样(实际上,读取资源的系统例程,主要是Resource Manager例程,现在为您做了大部分工作)。如果应用程序资源被存储在资源分支中,您可以用这些API来访问他们,但您现在必须为此明确指定资源分支。
将应用程序资源从资源分支中移出主要是为了使得应用程序能够在不同的文件系统中无缝地移动而不丢失资源。这些操作包括BSD命令,FTP,email和Windows与 DOS的copy命令。大多数计算机环境包括Web,只识别单一分支文件,这将会删除HFS和 HFS+文件的资源分支。
即使现在Apple建议在一个资源文件的数据分支中存储资源,但此对其本身并不是一个完善的解决方案。举个列子,存储在单个文件中的应用程序资源很难本地化。除了将应用程序资源从资源分支中移出外,您还应该使用应用程序打包安方案(请参见“应用程序打包”一章)并采取以下任何一步:
- 在应用程序束的本地化(或非本地化)区域,放置一个包含那一地区(或所有地区)的应用程序资源文件。按照惯例,这个文件应该具有一个.rsrc扩展名,虽然它可以包含任何扩展名或者没有扩展名。
- 把每个资源(或相关资源的组)放在它们自己的文件中而不是把所有本地化资源放在一个单一的.rsrc文件里。
图9-1 对照早期的Mac OS系统描述了Mac OS X中资源是如何存储的。
图9-1 数据分支中的资源
虽然Apple支持“在同一文件中存储所有资源(all-resources-in-one-file)”的模式,但强烈建议开发者将他们的资源存放在各自的独立文件中。基于此的一种考虑是为了结合XML的使用来作为来指示资源的一种方式。Carbon具有基于XML的运行时工具,Interface Builder可以使用XML来输出用户界面。
如同应用程序一样,Mac OS X上的文档也可将其资源存放在数据分支中。其原因与应用程序把资源存放在数据分支中的原因是相同的。它使得在Macintosh系统与非Macintosh系统(包括大部分的Web服务器)间交换文档,而不丢失资源数据成为可能。
存放在HFS 和HFS+文件系统中的文件在独立于资源分支和数据分支以外的一个私有分支中存储了Finder属性。这些属性包含了类型代码和创建者代码。Mac OS X保留了这些属性,因为这些属性能使Finder增强用户体验。然而同时,Apple强烈鼓励开发人员选择使用文件扩展名作为识别文件类型的方法。Mac OS X在识别和处理文档扩展名方面做的非常好。正如在“Finder”一章的“复制和移动操作”一节中所描述那样,如果您复制一个HFS 或HFS+文档到不同平台(包括Web服务器)中时,文件扩展名将有助于保证文档的类型信息。
虽然Unicode被认为是Mac OS X的基本编码,但并没有一种文件编码对所有情况都是默认的。使用(或应该使用)何种文件编码,取决于您在所使用的API和底层文件系统上具体想要做什么。
举个列子,用于文件名的编码在不同的文件系统中是不一样的。Mac OS 扩展格式文件系统(HFS+)使用一种Unicode的特殊形式为文件名编码,即在UTF-16格式(16位编码序列)中被规范出的Unicode 2.1版本。UFS文件系统使用一种不同的Unicode格式来编码文件名。它包含了Unicode2.1或更新版本中的任何字符,但使用的是UTF-8格式(8位编码序列)。Mac OS标准格式(HFS)使用传统的Mac编码,诸如MacRoman。注意,由于实现方式不同,在HFS+卷上文件名中不正确的Unicode编码有可能会在Mac OS 9系统上正常显示,但通常在Mac OS X上又显示成混淆的字符。
而且,所有调用BSD系统例程的代码都应保证这些例程的const *char参数是以UTF-8编码的。所有BSD系统函数期望其字符串参数以UTF-8编码,而不能是其他的编码。另外要告诫的是文件,路径和其他文件系统实体在作为字符串参数时必须要以规范的UTF-8编码。在规范的UTF-8 Unicode的字符串参数中,所有可分解的字符会被分解;举个例子,é (0x00E9)被表示为e (0x0065) + ′ (0x0301)。在使用在Cocoa和 Carbon (包括Core Foundation)中定义的"文件系统表示"API时,要以规范的UTF-8编码。举个例子,在Cocoa中得到一个规范的UTF-8字符串,要使用NSString的fileSystemRepresentation方法;而对非正规的UTF-8字符串,使用NSString的UTF8String方法。
如果您使用常规的QuickDraw并想绘制文本,您应注意一些潜在的问题。Carbon文件管理器会产生一些返回Mac编码的调用和其他一些返回Unicode的调用。如果您有一个Unicode文本,您在用QuickDraw Text对其绘制时会有一些问题,因为其API不直接支持Unicode。另一方面,如果您得到一个Mac编码的文本并想使用Unicode Imaging (ATSUI) API中Cocoa 和 Carbon的Apple Type Services,您必须首先将其转换成Unicode。
通常,所使用的编码取决于您使用的API而不是字体。字体并不必须限制于特定的编码。举个例子TrueType字体声明了一组字型,他们实现并提供了在特定编码中映射那些字型为字符值的编码表。PostScript字体有类似的编码列表。操作系统的各个部分知道如何映射字符从一种编码到另一种编码。Cocoa 和ATSUI使用Unicode作为一种字体的“目的”映射。Carbon 中的QuickDraw Text使用Mac编码,它是根据字体的'FOND'资源相对应的语系来选择的。
安装在Mac OS X上的字体拥有大量的字符组,它们支持广泛的编码和语系。举个例子,系统字体Lucida支持扩展的拉丁语(Latin), 希腊语(Greek), 斯拉夫语(Cyrillic), 阿拉伯语(Arabic), 希伯来语(Hebrew)和泰国语(Thai)。但如果您通过QuickDraw Text来绘制文本,那您只能访问MacRoman字符表。要访问其余的部分,则您必须使用Cocoa或 ATSUI。同样日语中的Hiragino字体也有一个巨大的字符表,它超越了MacJapanese所支持的范围,它们只有通过Cocoa 或ATSUI才可以访问到。当被请求的其他字体中的字型不可用时,Cocoa 和 ATSUI会将其替代;然而,他们替代字体的算法是不同的。
有关文件编码对多语系支持的更多信息,请参见“国际化”一章中的“加入多语系支持”一节。
[ 返回 ]