在运行时读取可执行文件中的数据

3

你好!

我有一个可执行文件(Unix或Windows - 它应该是跨编译的)。如果一个人通过任何编辑器打开这个可执行文件并在结尾写入一些内容,应用程序仍然可以完美运行。在执行时,应用程序及其所有数据加载到RAM中。因此,用户写入的文件部分也加载到了内存中。

有没有可能读取这些数据?

我需要快速访问这些数据。其他变通方法不可行,因为它需要太多时间:

  1. 直接从文件(硬盘上)读取或映射不好,因为应用程序必须在每次运行时读取此文件,但这个应用程序每秒都有很多启动。
  2. 使用另一个进程(像服务器一样持有数据)的共享内存不是跨编译的。
  3. 使用应用程序和所谓的服务器之间的管道不够快,我认为。

这就是为什么我决定在应用程序结尾写入一些内容。

提前致谢!


1
我不确定,仅作为评论:你不应该做这样的事情。操纵构建可执行文件并添加一些数据到结尾可能会破坏二进制文件。你应该创建一个额外的数据文件。根据数据类型,你应该在启动时将文件作为资源打开并将内容存储到内存中。或者你必须将数据编译到你的可执行文件中。 - Thomas Berger
Thomas,问题在于将数据添加到末尾不会破坏二进制本身。使用额外的文件会耗费时间。存储的数据基本上是普通文本。 - serenheit
你说的“耗时”是什么意思?这是全世界都在做的事情!此外,这对代码签名等方面有影响。 - Joe
@serenheit 使用文本编辑器(在最坏的情况下,Windows 上的记事本)编辑二进制文件会破坏二进制文件。您不应该这样做。不要使用文本编辑器。 - Thomas Berger
@Joe 时间消耗意味着读取文件约占程序工作时间的50%。这部分必须非常快,因为我有一个接收大量对该二进制文件请求的服务器。 - serenheit
@serenheit:你应该知道有一个页面缓存的存在吧?每秒将同一文件读入内存数千次只会将页面从页面缓存重新映射到用户空间,最坏的情况下进行memcpy...这对于内存映射来说更是如此。 - Damon
1个回答

4

您是否正在重新发明

我还认为,您可能正在优化错误的内容。

直接从磁盘上读取文件或将其映射并不好,因为每次运行应用程序都必须读取此文件,但是该应用程序每秒启动很多次。

内核[1]比我们聪明得多,并且完全能够缓存已映射的内容。该死的,如果您将其映射为只读,则与从程序的基本映像直接访问数据没有任何区别。

[1]:这适用于Windows和Unix


如果我没记错的话,我会在进程开始时映射文件,然后在结束时取消映射。我不认为内核会缓存它。但是...也有可能。我会尝试找一些相关信息。 - serenheit
2
@serenheit 内核会进行缓存,这就是它具有文件系统缓存的原因。 - Thomas Berger
@serenheit 文件内容将从文件系统缓存(RAM)中提取,没错。请定义您所说的映射是什么意思。如果您的意思是将文件映射到内存中,则应该比从文件本身读取更快。 - Thomas Berger
1
无论是映射还是读取,都有块缓存。实际块已经在RAM中,因此它们只是重新映射到进程空间(如果映射是只读的,则共享)。重新打开相同的映射不需要磁盘访问,除非文件已更改。 - sehe
@Sehe 谢谢,我会尽力制作一些非常困难的测试来确定最佳方法。 - serenheit
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接