3

我正在编写一个游戏项目作为一种爱好,目前我需要将一些资源数据(例如.BMP)存储为我自己的文件格式,以便我的游戏可以解析所有这些数据并加载到屏幕。

为了读取 BMP,我读取标题,然后读取每个像素的 RGB 数据,并且我有一个存储这些值的数组 [宽度] [高度]。

有人告诉我应该将这些类型的数据保存为二进制,但不是原因。我已经阅读了二进制及其是什么(数据的 0-1 表示),但我为什么要使用它来保存 .BMP 数据?如果我稍后在游戏中阅读它,它不是只会增加更多的复杂性,甚至可能会减慢加载过程吗?

最后,如果最好保存为二进制文件(我猜是这样,从我在其他游戏资源文件中研究的内容来看,每个人似乎都是这样做的)我如何在 C++ 中读写二进制文件?我已经看到了很多问题,但是对于许多不同类型的变量有很多不同的方法,所以我在问哪种方法是最好的/更 C++ 的方法?

4

1 回答 1

9

你有这一切。计算机处理器处理二进制级别的数据。计算机中的一切都是二进制的。为了以人类可读的形式处理数据,我们编写了一些函数,这些函数可以跳过箍,使二进制数据看起来像人类可以理解的东西。因此,如果您将 .BMP 数据作为文本存储在文件中,您实际上会让计算机做更多的工作来将 .BMP 数据从其自然二进制形式转换为文本,然后再从其文本形式转换回二进制为了显示它。

事实是,您处理原始二进制形式的数据越多,您的代码运行速度就越快。更少的转换意味着更快的代码。但显然有一个折衷:如果您需要能够查看数据并理解它而不需要拿出一个神奇的解码器环,那么您可能希望将它作为文本存储在一个文件中。但在这样做时,我们必须了解必须进行转换处理才能使人类可读的文本对处理器有意义,正如我所说,处理器只对纯二进制数据进行操作。


而且,以防万一您已经知道或知道它,而您的问题是“为什么我应该以二进制模式而不是文本模式打开我的 .bmp 文件”,那么原因是打开一个文本模式下的文件要求平台根据平台执行必要的 CRLF 到 LF 转换(“\r\n”到-“\n”转换),以便在内部字符串处理级别,所有你正在处理的是 '\n' 字符。如果您的文件包含二进制数据,则您不希望继续进行该转换,否则它会在您读取文件时损坏文件中的数据。在这种状态下,大部分数据都可以正常工作,并且大部分时间都可以正常工作,但有时您会遇到一对十六进制形式的字节 0x0d,0x0a(十进制 13,10),它们将被转换到 0x0a (10), 你会在你读取的数据中丢失一个字节。因此一定要以二进制模式打开二进制文件!


好的,根据您最近的评论(如下),这是:

正如您(现在?)所了解的那样,计算机中的数据以二进制格式存储。是的,这意味着它在 0 和 1 中。但是,在编程时,您实际上不必自己摆弄 0 和 1,除非出于某种原因您正在执行按位逻辑运算。比如说一个类型的变量,int比如说是一个个位的集合,每个位可以是0或者1。它也是一个字节的集合,假设一个字节有8个位,那么一般有2个、 4 或 8 个字节int,具体取决于您的平台和编译器选项。但是您将其int用作int,而不是单独的 0 和 1。如果你这样写int以最纯粹的形式输出到文件中,字节(以及位)以未转换的原始形式写出。但是您也可以将它们转换为 ASCII 文本并以这种方式写出来。如果你在int屏幕上显示一个,你当然不想看到单独的 0 和 1,所以你以 ASCII 格式打印它,通常解码为十进制数。您可以轻松地int以十六进制形式打印它,即使它是相同的数字,结果也会看起来不同。例如,在十进制中,您可能有十进制值 65。同样的十六进制值是 0x41(或者,如果我们知道它是以 16 为基数的,则只有 41)。如果我们以 ASCII 格式显示它,那么相同的值就是字母 'A'(并且只考虑 2,- 4,- 或 8-byte 的低字节int,即char)。

对于本次讨论的其余部分,忘记我们在讨论一个int,现在考虑我们正在讨论一个char,或 1 个字节(8 位)。假设我们仍然有相同的值,65,或 0x41,或“A”,但是您想查看它。如果您想将该值发送到文件,您可以将其以原始形式发送,也可以将其转换为文本形式。如果以原始形式发送,它将占用文件中的 8 位(一个字节)。但是,如果您想以文本形式将其写入文件,则将其转换为 ASCII,这取决于您要写入实际值的格式(在本例中为 65),它将占用 1、2 ,或 3 个字节。假设您想用没有填充字符的十进制 ASCII 编写它。然后值 65 将占用 2 个字节:一个用于“6”,一个用于“5”。如果你想以十六进制形式打印它,它仍然需要 2 个字节:一个用于“4”,一个用于“1”,除非你在它前面加上“char是值 255(a 的最大值char):如果我们以十进制 ASCII 形式将其写入文件,它将占用 3 个字节。但是,如果我们以十六进制 ASCII 形式写入相同的值,它仍将占用 2 个字节(或 4,如果我们在前面加上“0x”),因为十六进制的值 255 是 0xFF。char将此与以原始二进制形式写入 8 位字节 ( ) 进行比较:Achar占用 1 个字节(根据定义),因此无论其值是什么,它都只会以二进制形式消耗文件的 1 个字节。

于 2013-02-01T16:14:41.937 回答