从一个文件快速轻松地加载所需内容
本文关键字:加载 一个 文件 | 更新日期: 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进行简单的指导设计)
它们的作用各不相同,但基本上达到了相同的最终结果。这完全取决于你在寻找什么。