为什么以及如何从二进制文件中读取和读取?

Dan*_*cco 3 c++ binary binaryfiles

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

为了读取BMP,我读取了标题,然后是每个像素的RGB数据,我有一个存储这些值的数组[width] [height].

我被告知我应该用二进制保存这些类型的数据,但不是原因.我读过关于二进制及其内容(数据的0-1表示),但为什么我应该用它来保存.BMP数据呢?如果我稍后会在游戏中阅读它,它是否只会增加更复杂性甚至可能减慢加载过程?

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

pho*_*ger 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字节的低字节,即将int其视为a char).

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