主要这似乎是游戏使用的一种技术,它们将所有声音放在一个文件中,将纹理放在另一个文件中等。这些文件通常达到 GB 大小。
这样做的原因是什么,而不是将所有子目录中的所有内容都作为小文件进行维护——每个纹理一个,许多小游戏都使用它,而大公司更喜欢单片系统?
大量小文件是否存在一些文件系统开销?他们是否试图保护他们的财产——尽管大多数似乎只是一个带有新扩展名的压缩文件?
主要这似乎是游戏使用的一种技术,它们将所有声音放在一个文件中,将纹理放在另一个文件中等。这些文件通常达到 GB 大小。
这样做的原因是什么,而不是将所有子目录中的所有内容都作为小文件进行维护——每个纹理一个,许多小游戏都使用它,而大公司更喜欢单片系统?
大量小文件是否存在一些文件系统开销?他们是否试图保护他们的财产——尽管大多数似乎只是一个带有新扩展名的压缩文件?
我们在我工作的地方(一家游戏开发公司)使用这样的“存档”系统的原因:
hash( normalized_filename ) -> [ offset, size ]
查找文件。我们还可以将此索引保存在 RAM 中,可能会将其与其他索引表交错,等等。.arc
,或者我们可以在某处存储文件名列表、文件名哈希列表或 [offset, size] 对列表 - - 甚至可以作为存档中的文件。这通常比 FS 上的目录遍历更快。)但这些都是世俗的原因。更有趣的东西:
每个.arc
寄存器都在一个列表中,并尝试打开一个知道要查看弧的文件。我们首先搜索 RAM 中的存档,然后是设备 FS 上的存档,然后是实际的设备 FS。这给了我们很大的灵活性:
.wad
系统就是上述的一个例子,它允许模组制作者更容易地覆盖游戏中内置的资产和脚本。)bin2obj
将整个弧直接嵌入到可执行文件 ( .rodata
) 中,此时您无需查看设备 FS - 我们为某些小型演示版本执行此操作之类的。我们也可以通过这种方式通过网络发送关卡或保存游戏-运动鞋网。=)我们最近将 PC 游戏移植到了 FS 访问速度慢得多的系统。我们没有改变数据格式,结果证明遍历原始设备 FS 上的一个目录来加载一百个小的 XML 文件绝对会浪费我们的加载时间。我们使用的解决方案是获取每个目录,使其成为自己的subdir.arc
,然后将其粘贴在game.arc
压缩的主目录中。当需要 dir 时(调用 opendir 之类的东西),我们将整个 subdir.arc 解压缩到 RAM 中,将其添加到文件系统中,然后超快速地迭代它。
能够在几个小时内将这样的东西放在一起,并减轻跨系统移植的痛苦,这使得这样的东西变得有价值。
文件系统确实有开销。通常,一个文件占用的磁盘空间向上取整为 2 的某个幂(例如,最多 4 KB),所以很多小文件会浪费空间。一些现代文件系统试图缓解这种情况,但 AFAIK 尚未普及。此外,文件系统在访问多个文件时通常非常慢。例如,复制一个 400 MB 的文件通常比复制 4000 个 100 KB 的文件要快得多。
当您必须修改文件时,文件系统会派上用场,因为它们比任何简单的本土解决方案都能更好地处理文件大小的变化。但是,对于恒定的游戏数据,情况肯定不是这样。
在 Apple 系统上,最常见的方法是按照您的建议使用目录。它们被称为 Bundle,在 Finder 中仅表示为一个文件,但如果您进一步探索它们,它们实际上是目录。这使得在从这个包中加载单个项目时编写代码和节省内存变得非常容易。:-) 此外,这使得对巨大数据库进行增量备份变得容易,例如您的 iPhoto 数据库只是一个捆绑包,因此您只需备份更改的文件和新文件
然而,在 Windows 上,我相信这更难做到,它看起来像一个“无论如何”的目录(我相信聪明的人已经找到了一个解决方案,可以让资源管理器将某些目录视为单个文件,但它是不常见)。
从游戏开发人员的角度来看,您不会处理如此小的文件,以至于磁盘空间开销是您非常关心的事情,所以我怀疑@doublep 的建议,因为它会带来如此麻烦,但确实如此如果用户要将整个游戏复制到某个地方,使用单个文件会容易得多,那么很容易检查整个集合是否正确。
而且,当然,对于不应该访问它的人来说,它更难阅读。但它也更难修改,这意味着更难修补,更难编写扩展。经常使用扩展的人更喜欢目录结构:The Sims。
如果我是游戏开发者,我会喜欢单独的文件。再说一次,我会像为 Mac 写东西一样使用捆绑软件 ;-)
干杯
尼克
我可以想到多种原因。
正如 doublep 建议的那样,文件在磁盘上占用的空间比它们需要的要多。所以存档可以节省空间。10k 个文件(任何大小)在打包到存档时应该可以节省 20MB。现在不是很大的空间,但仍然。
我能想到的另一个原因是磁盘碎片。我怀疑在访问碎片空间上的数千个单独文件时,碎片严重的磁盘会表现得更差。但我不是这个领域的专家,所以如果有经验丰富的人证实这一点,我将不胜感激。
最后,我认为这也可能与限制对单独游戏文件的访问有关。你可以暴露一堆 Lua 脚本,弄乱它们并破坏一些东西。或者,您可以将结尾的电影/声音/文本/任何内容暴露出来,并通过访问它而被宠坏。我自己也这样做:我使用多通道 XOR 密钥加密图像,将文本文件和配置变量打包成一个整体文件(压缩以提高安全性),并且只让音乐自由访问。这样一来,游戏的秘密将不会被发现更长时间:)。
或者可能还有另一个我从未想过的原因:D。
如你所知,游戏,尤其是大公司试图尽可能多地压缩性能。一种技术是将所有数据放在一个大文件中,然后将其 DMA 到内存(将其视为从 CD 到 RAM 的 memcpy)。由于所有文件都在一个大文件中,因此不会进行磁盘搜索,并且由于该技术,您可以快速加载大量文件(这可能会导致大量搜索)。