2011-10-27 67 views
2

我忙着里面有很多像图片中的文字文件和其它数据的东西一点点的项目,我想收拾这一切,在一个大的文件或多个大文件,这样的程序文件夹看起来不杂乱。编辑大型二进制文件

但问题是如何编辑这些文件。我想到了文件的结构和它的将是这样的:

 
[DWORD] Number of files 

    [DWORD]FileId 
    [STRING]FileName 
    [DWORD]FileSize 
    [DWORD]FileIndex 

[BYTES]All the files 

所以第一部分是太快让所有的文件列表和FileIndex是二进制文件中的位置,所以我可以设置指针,例如300,并读取文件。

但是,如果我想创建一个补丁,并修改它,我要读我编辑的文件之后的所有字节,并复制它们都回来了,可把年龄了几个文件。

当所有的文件插入的二进制文件可数100 MB的。

那么如何其他程序,例如游戏要这样做使用这些大文件,并修补了很多有某种把戏更快地插入额外的字节?

+3

出于好奇,谁将会看着你的节目目录,并且看起来很杂乱?通常人们不需要关心你的程序的目录。 –

+0

是的,你说的对,但我只是想提高我的编程技能,尝试不同的东西,现在我正在使用文件系统,我可以自己找出这个问题 – Kevin

回答

0

的不是办法插入字节到比你所描述的其他文件。这与编程语言无关。这只是文件系统的工作原理...

你可以覆盖部分文件,但只有你尊重字节数。

1

你可以把包装和编辑程序有点像一个自定义的内存分配器:

  1. 使用最小的块大小 - 当你添加一个文件,使用足够的全 块,以适应该文件。这会自动给文件一些空间 增长而不影响其他文件。
  2. 当文件变得太大以至于当前分配时,将其移动到包的末尾。
  3. 标记空闲块的自由,并保持偏移到包报头中的 空闲链表的头。当添加其他文件时,首先检查是否有足够大的空闲块。
  4. 将文件扩展到当前块之后时,请检查以下块是否位于空闲列表中。
  5. 如果空闲列表太长(碎片太多),请整理软件包。将每个文件向前移动以在第一个空闲块中开始。这将不得不重新编写整个文件,但很少会发生。

或者,您可以使用类似于FAT的简单目录来代替简单的目录。对于每个文件,存储块和大小的列表。当你扩展一个文件超过它当前的分配时,添加其余的块。偶尔根据需要进行碎片整理。

这两个都会给包增加一点开销,但留下的空隙实际上是重写每个插入内容的唯一选择。

+0

这就是非常粗略的, FAT如何工作。 – littleadv

+0

我也会将这些文件分割以节省空间。 –

3

在文件中间插入字节没有“窍门”。

通常的解决方案包括将文件添加到文件末尾,然后切换它们在索引中的位置。然后你遇到了不得不整理文件的问题。你可以将文件分割成大块,这可以减轻碎片整理的困扰,但是这些文件不是连续的。

如果您正在处理非静态数据,我不会建议您这样做,除非您绝对必须这样做。我见过绝对出色的软件工程师需要花费大量的时间来编写合理的实现。

使用sqlite作为虚拟文件系统可能是一个可行的解决方案。但是,再一次,将数据文件放在另一个文件夹中,以免看起来“杂乱”。

1

诀窍是通过覆盖数据来制作补丁。否则,就有可用于管理大量数据的系统,例如数据库。

您可以创建一个伴随程序的数据库文件,并将所有数据保存在那里,而不是保存在文件中。您甚至可以将数据库代码嵌入到您的应用程序中,例如SQLite,或者使用外部数据库,如Sql Server,Oracle SQL或MySql。

你所描述的基本上是实现你自己的文件系统。这是一项棘手而且非常艰巨的任务。

0

您是否想过使用.zip文件?我一直在看看那里有多个文件存储为一个的格式,而底层文件实际上是一个zip文件。关于这一点的好处是,zip库为你处理低级位跟踪的东西。

几个例子浮现在脑海:

  • 一个字.docx文件确实是一个zip(重命名一个为.zip,你可以打开它 - 它拥有整个文件夹中的话)
  • Silverlight包使用的.xap文件是另一个。
+0

Java的'.jar'文件用zip程序打开,但它们不是_technically_拉链的一些技术性我没有看过。 –

3

如果可能的话,我可能会将数据打包成zip文件。这不仅会清理你的目录,而且(特别是对于你提到的文本文件)基本上是免费的。当然,还有一些现有的工具和库用于创建,检查,修改压缩文件等。

使用zlib(举一个例子),大部分工作都是为您处理的(例如,如minizip所示)。

0

您可以使用一个托管共享内存,由内存映射文件支持。您仍然必须为整个文件提供足够的地址空间,但不需要将整个文件复制到内存中。尽管您可以很快发现指定自定义分配器无处不在,但您可以使用大多数具有共享内存分配器的标准设施。但好消息是,你不需要自己实现这一切,你可以采取Boost.Interprocess,它已经有所有必要的设施,为Unix和Windows。