我正在编写一个游戏项目作为业余爱好,我目前正处于需要将一些资源数据(例如.BMP)存储到我自己的文件格式中的部分,因此我的游戏可以解析所有这些并加载到屏幕上。
为了读取BMP,我读取了标题,然后是每个像素的RGB数据,我有一个存储这些值的数组[width] [height]。
有人告诉我应该用二进制保存这些类型的数据,但不是原因。我读过关于二进制及其内容(数据的0-1表示),但为什么我应该用它来保存.BMP数据呢? 如果我稍后会在游戏中阅读它,它是不是只会增加更复杂性甚至可能减慢加载过程?
最后,如果以二进制保存更好(我猜是这样,看看每个人似乎都是从我在其他游戏资源文件中研究的那样做的)我如何在C ++中读写二进制文件? 我已经看到很多问题,但是对于许多不同类型的变量有许多不同的方法,所以我问的是哪种方法最好/更多C ++的方法呢?
答案 0 :(得分:9)
你完全倒退了。计算机处理器使用二进制级别的数据进行操作。计算机中的所有东西都是二进制的。为了处理人类可读形式的数据,我们编写了跳过箍的函数,使二进制数据看起来像人类理解的东西。因此,如果将.BMP数据作为文本存储在文件中,您实际上是在使计算机完成更多工作,将.BMP数据从其自然二进制形式转换为文本,然后从其文本形式返回二进制以显示它。
事情的真相是,您以原始二进制形式处理数据越多,您的代码运行得越快。转换次数越少意味着代码越快。但显然需要权衡:如果您需要能够查看数据并理解它而不拔出魔术解码器环,那么您可能希望将其作为文本存储在文件中。但是在这样做的时候,我们必须明白,必须要进行转换处理才能使人类可读的文本对处理器有意义,正如我所说的那样,只对纯二进制数据进行操作。
而且,万一你已经知道或者知道它,你的问题是"为什么我要以二进制模式而不是文本模式打开我的.bmp文件"然后原因是在文本模式下打开文件要求平台执行CRLF到LF的转换(" \ r \ n" -to - " \ n"转换),根据平台的需要,在内部字符串处理级别,您所处理的所有内容都是' \ n'字符。如果您的文件包含二进制数据,则不希望转换继续进行,否则在您阅读时会损坏文件中的数据。在这种状态下,大多数数据都可以正常运行,并且大多数情况下都可以正常工作,但偶尔你会遇到十六进制格式0x0d,0x0a(十进制13,10)的一对字节。转换为只有0x0a(10),你将在你读取的数据中丢失一个字节。因此,请务必以二进制模式打开二进制文件!
好的,根据您最近的评论(如下),请点击此处:
正如您(现在?)所理解的那样,计算机中的数据以二进制格式存储。是的,这意味着它出现在0和1之间。但是,在编程时,除非您因某种原因进行按位逻辑运算,否则您实际上不必自己动摇0和1。例如,类型的变量,例如int
,是各个位的集合,每个位可以是0或1.它也是字节的集合,并假设一个字节中有8位,然后int
中通常有2个,4个或8个字节,具体取决于您的平台和编译器选项。但是,您使用int
作为int
,而不是单独的0和1。如果以最纯粹的形式将int
写入文件,则字节(以及位)将以未转换的原始形式写出。但您也可以将它们转换为ASCII文本并以这种方式写出来。如果您在屏幕上显示int
,您当然不想查看个人0和1,所以您要以ASCII格式打印,通常解码为十进制数。您可以轻松地以十六进制形式打印相同的int
,即使它的数字相同,结果也会有所不同。例如,在十进制中,您可能具有十进制值65.十六进制中的相同值是0x41(或者,如果我们理解它在基数16中,则仅为41)。同样的价值是字母' A'如果我们以ASCII格式显示它(并且只考虑2, - 4, - 或8字节int
的低字节,即将其视为char
)。
对于本讨论的其余部分,请忘记我们正在讨论int
,现在考虑我们正在讨论char
或1字节(8位)。让我们说我们仍然有相同的值,65或0x41,或者' A'但是你想看看它。如果要将该值发送到文件,可以以原始格式发送,也可以将其转换为文本格式。如果以原始格式发送它,它将占用文件中的8位(一个字节)。但是如果你想以文本形式将它写入文件,你可以将它转换为ASCII,这取决于你想要写的格式实际值(在这种情况下为65),它将占用1 ,2或3个字节。假设你想用十进制ASCII写它而没有填充字符。然后,值65将占用2个字节:一个用于' 6'一个用于' 5'。如果你想以十六进制格式打印它,它仍然需要2个字节:一个用于' 4'一个用于' 1',除非你在" 0x"之前加上它,在这种情况下它需要4个字节,一个用于' 0',一个用于& #39; x',一个用于' 4'另一个用于' 1'。或者假设您的char
是值255(char
的最大值):如果我们以十进制ASCII形式将其写入文件,则需要3个字节。但是如果我们用十六进制ASCII格式写出相同的值,它仍然需要2个字节(或4个,如果我们在前面加上" 0x"),因为十六进制的值255是0xFF。将其与以原始二进制形式写入8位字节(char
)相比较:A char
占用1个字节(根据定义),因此它将仅消耗二进制形式的文件的1个字节,它的价值是什么。