从一个文件快速轻松地加载所需内容

本文关键字:加载 一个 文件 | 更新日期: 2023-09-27 18:22:49

想象一下,有一个游戏有很多内容,比如汽车模型。我不想为了节省内存而一直把它们放在RAM中,只想在需要的时候加载它们。当每辆车有一个文件时,这会很容易,但我最后会有很多文件,项目会变得很难共享等。

但当我把所有东西都存储在一个文件中时,我不知道什么在哪里。有没有一种方法可以将所有内容存储到一个文件中,并像我为每个内容条目创建一个文件一样轻松地导航到内容?我唯一能想到的是保存第二个文件中开始的字节位置(或内容文件中的头),但我对这个解决方案非常不确定。

从一个文件快速轻松地加载所需内容

一个简单的方法是,当你写文件时,你要跟踪(内存中)东西的位置。然后,在文件的末尾写一个索引。所以你的文件看起来是这样的:

offset 0: data for object 1
offset 0x0473: data for object 2
offset 0x1034: data for object 3
etc.

您可以使用BinaryWriter编写此文件。在编写每个对象之前,查询writer.BaseStream.Position以获取文件的当前位置。您将该信息保存在内存中(仅保存对象名称及其位置)。

当你写完所有对象后,你保存当前位置:

indexPosition = writer.BaseStream.Position;

然后在文件末尾写入索引:

name: "object 1", position: 0
name: "object 2", position: 0x0473
etc.

写一个空的索引条目来表示对象的结束:

name: "", position: 0xFFFFFFFF

最后一件事是在文件末尾写下索引位置:

writer.Write(indexPosition);

现在,您可以使用BinaryReader打开该文件。查找文件末尾减去8个字节,读取其中的长整数。这会给你指数的位置。查找索引并开始向前读取索引项,直到找到位置为0xFFFFFFFF的索引项为止。

您现在已将索引存储在内存中。您可以创建一个Dictionary<string, long>,这样在给定对象名称的情况下,您就可以找到它在文件中的位置。找到位置,在那里寻找,然后阅读物体。

这种事情在90年代末我们写游戏的时候很常见。您仍然可以这样做,尽管使用简单的数据库可能会更好。

如果您想将文件临时存储在一个更大的文件中进行传输,可以使用多种不同的压缩和归档方法来保存文件。几乎任何压缩方法都可以工作,您选择哪种方法完全取决于您。

示例.zip压缩可以在这里找到:http://msdn.microsoft.com/en-us/library/ms404280.aspx

还有.cab文件格式,您可以轻松地将多个文件打包到其中,并在以后需要时进行解压缩。这里有一篇关于在C#中创建.cab文件的有趣文章:

http://mnarinsky.blogspot.com/2009/11/creating-cab-file-in-c.html

它确实需要添加对Microsoft.Deployment.Compression.Cab.dll和Microsoft.Deployment.Compression.dll的引用,但之后代码本身相当简单。如果你觉得这些都不是你问题的合适答案,我唯一的其他建议是,你最好把文件组织起来,而不是把它们都塞进一个文件夹里,因为这会让导航变得很困难。

如果有帮助的话,也可以尝试使用集合来跟踪文件名。如果需要更动态,您可以在XML中定义文件,并将所有内容加载到字典或哈希表中,或者如果您喜欢,可以在代码本身中定义它。

编辑:

您也可以尝试使用第三方安装程序进行传输。它们提供了压缩和打包文件之外的许多功能,并将为您处理数据压缩。我个人更喜欢NSIS,因为我发现它对用户非常友好,但任何安装程序都可以工作。一些示例安装程序有:

Installshield:http://www.installshield.com/(与Visual Studio集成)

WIX:http://wix.sourceforge.net/(还与Visual Studio集成,如果您正在寻找更基于XML的东西,这很好)

NSIS:http://nsis.sourceforge.net/Main_Page(可编写脚本,不与Visual Studio集成,如果你不想自己编写大部分脚本,可以使用Nsisqssg进行简单的指导设计)

它们的作用各不相同,但基本上达到了相同的最终结果。这完全取决于你在寻找什么。