【问题标题】:Load needed content from one file fast and easily?快速轻松地从一个文件加载所需内容?
【发布时间】:2013-07-16 11:36:41
【问题描述】:

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

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

【问题讨论】:

  • 听起来你想在这里重新发明轮子。你到底想完成什么需要这么多文件?
  • 为什么不使用小型数据库?
  • 我的意思是你可以把所有东西都打包成一个存档,然后在安装时解压,或者在程序运行时解压到缓存中。
  • 这不取决于你,文件系统缓存无论如何都会将它保存在 RAM 中。这不是问题。
  • 我知道,只是指出认为您可以控制 RAM 中的内容是白日梦。这不是操作系统的工作方式。你不能把东西放在 RAM 里,你也不能把它放在外面。

标签: c# windows io


【解决方案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 轻松引导设计)

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

【讨论】:

    【解决方案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 年代后期编写游戏时,这种事情很常见。您仍然可以这样做,尽管使用简单的数据库可能会更好。

    【讨论】:

    • 这样做并且效果很好:) 否则我会得到 +2000 个文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 2019-09-03
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    相关资源
    最近更新 更多