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

时间:2013-07-17 18:50:31

标签: c# windows io

想象一下,有一个包含很多内容的游戏,比如汽车模型。 我不想一直将它们放在RAM中以节省内存并且只在需要时才加载它们。当每辆车有一个文件时,这很容易 - 但我最后会有这么多文件,而且项目很难分享等等。

但是当我将所有内容存储到一个文件中时,我不知道它在哪里。 有没有办法将所有内容存储到一个文件中并像每个内容条目一样轻松导航到内容?我唯一可以想象的是保存第二个文件中的字节位置(或内容文件中的标题),但我对此解决方案非常不确定。

2 个答案:

答案 0 :(得分:2)

一种简单的方法是在你编写文件时跟踪(在内存中)内容。然后,在文件的末尾编写索引。所以你的文件看起来像这样:

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年代后期写游戏时,这种事情很常见。你仍然可以做到这一点,尽管你最好还是选择一个简单的数据库。

答案 1 :(得分:1)

如果您希望将文件临时存储在较大的文件中以进行传输,可以使用相当多的不同压缩和存档方法来保存文件。几乎任何压缩方法都可以使用,您选择的完全取决于您。

示例.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进行简单的指导设计)

它们的功能各不相同,但基本上可以达到相同的最终结果。这完全取决于你正在寻找什么。