【问题标题】:How do Binary Files works? (From c++'s point of view) [closed]二进制文件如何工作? (从c ++的角度来看)[关闭]
【发布时间】:2014-11-16 02:50:56
【问题描述】:

我对二进制文件有一些误解,我不明白二进制文件是什么,我知道文本文件也是二进制文件,但它需要解析才能提取信息,不像文本文件具有相同内容的二进制文件看起来不同,例如,将我的名字存储在二进制文件“Rishabh”中时,它不仅将 Rishabh 存储在该文件中,而且还有一些额外的不可读字符,它是什么?为什么它不只存储文本文件之类的字符,以及什么是二进制文件格式,例如。 .3d、.zip、.mp3 等...根据我对文本文件的了解,格式扩展名指定格式是什么或如何处理该文件,例如 .dae、.xml、.htm 等...这些包含标签存储数据,但是二进制文件呢,因为它不需要任何标签,因为它作为变量存储在那个文件中,我们必须从中复制内容到程序变量,(我的意思是说它就像存储在内存中)所以为什么这些二进制文件格式是不同的,为什么不仅仅是一个程序读取世界和我都不知道的文件的所有内容?还有什么是二进制文件格式破解??

【问题讨论】:

  • 也许一个定义是这样的:文本文件是二进制文件,遵循一种约定,只包含文本可打印字符。要实现这个数字(例如)需要转换成文本形式。
  • 我知道,我想了解二进制文件,你能解释一下二进制文件吗?还有什么叫二进制文件格式破解??
  • 投反对票,因为帖子不够集中/过于笼统。

标签: c++ file parsing binary


【解决方案1】:

所有文件都具有某种预先确定的编码,因为计算机除了以字节为单位的位模式之外无法在磁盘上存储任何内容。一个文本文件只包含可打印字符加空格的编码,很少有其他编码用于换行符、制表符、可能还有换页符以及其他一些与设备上的字符显示相关的编码。因为文本文件中的编码是一个众所周知的标准,而且非常普遍,所以大多数语言(如果不是所有语言)都有专门处理该类型文件的函数。最重要的是,他们知道如何一次读取一行 - 他们识别行终止符。

但是,如果您在除文本编辑器之外的其他程序中键入您的姓名字符 - 假设您使用 Gimp 或 Microsoft Paint 中的文本工具编写,然后保存它。该程序必须保存更多信息,而不仅仅是您的姓名。您的名字在画布上的位置必须保存。它还有字体和大小,无论是粗体、斜体还是下划线,都需要保存。需要保存画布的大小。使用的颜色,即使是白色和黑色,也需要保存。此编码将不同于用于保存您的姓名字母的编码。因此,如果您使用文本编辑器编辑文件,您会看到一些乱码,因为文本编辑器需要字符编码,并且对 Gimp 用于字体、字体大小、x、y 位置等的编码一无所知。

C++ 编译器没有编写用于理解任何二进制文件编码的例程。在 C++ 中读取/写入二进制文件的例程只会读取和写入字节序列。虽然,由于在 C++ 中保存数据字节的基本类型是 char(或 unsigned char),但您会看到像

这样的二进制原型
write ( char * buffer, streamsize size );
 read ( char * buffer, streamsize size );

但在这种情况下,char 指针应该被视为“字节 *”,因为读/写函数只是将数据字节从/向磁盘或内存移动,而不考虑字符编码。

C++ 读/写例程不知道也不关心它们移动的字节的格式或编码是什么。因此,程序员可以根据文件的预定义格式编写代码来处理或处理这些字节。但是,为处理特定格式的二进制文件而编写的例程可以编译成库,然后可以共享或出售,并供许多 C++ 程序员使用。例如,LibXL 可用于从 C++ 程序中读取二进制格式的 Excel 文件。

【讨论】:

    【解决方案2】:

    从 C/C++ 的角度来看,文本文件和二进制文件的区别在于行尾的处理方式。

    如果您以二进制模式打开文件,则read 会准确读取文件中的字节,write 会准确写入内存中的字节。

    如果您以文本模式打开文件,则通常用于表示文件中行尾的任何字符或字符序列都将转换为某个单个字符(在源代码中写为'\n',虽然它只有一个字符),当读取文件时,\n 在写入文件时转换为常规的行尾字符或序列。此外,从技术上讲,文件不以行尾序列结尾是不合法的,并且可能对行的长度有限制。

    在 Unix 中,这两种模式是相同的,因为\n 是字符代码 10(十六进制的0A)的表示,而这正是传统的行结束字符。相比之下,在 Windows 中,传统的行结束序列是两个字节长——{10,13}{0A,0D}\n 仍然是0A,所以0A 之后的0D 会从从文件读取的数据中删除,而0D 会在数据写入文件时在每个0A 之后插入。

    一些(很多)较旧的操作系统根本没有传统的行尾字符;相反,所有行都用空格字符填充到完全相同的长度,从而可以直接查找特定的行号。在文本模式下工作的 C 库通常会准确读取行长,然后删除尾随空格并添加与 \n 对应的代码(某些此类系统使用 EBCDIC 而不是 ASCII,因此 \n 是不同的整数值)。写出数据,\n 将被删除并替换为正确数量的空格,以使该行达到标准长度。幸运的是,我们这些不在计算机博物馆工作的人不必再处理这些东西了,随着 OSX 的出现,Apple 放弃了使用{13,10} 作为行尾序列,所以文本/binary 差异现在仅限于 Windows。

    【讨论】:

      【解决方案3】:

      从技术上讲,文本文件是二进制文件,因为所有文件实际上都是二进制文件。文本文件往往只存储文本字符,而二进制存储任何可能的值 - 数字、图像、文本等。例如,数字不以十进制表示法存储,如“1234”,它们将使用 0 和 1 以二进制存储只要。有几种方法可以做到这一点(取决于您的操作系统),因此相同的数字可能看起来像一组不同的 0 和 1。例如0001110101011等。如果你在记事本中打开二进制文件,它会尝试将所有内容显示为文本,而你看到的也是一些垃圾,这是二进制表示的其他数据。

      破解二进制文件格式就是确切地知道文件的每个字节中存储了哪些信息……有时是文本、数字、数组、类、结构……任何东西。有经验的人可以慢慢弄清楚什么是什么,但那是相当高级的东西!

      有时信息(格式)是免费提供且易于理解的,或者像 MS Word 文档的格式一样难以理解。 (MS Word 格式是免费提供的,但由于向后兼容性而被认为非常复杂......尽管如此,拥有格式文档可以让您“破解”二进制文件格式并确切知道所有二进制文件代表什么)

      它是计算机系统的基础之一。

      在这个链接中可能是一个很好的解释

      http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/asciiBin.html

      引用的一些文字:

      虽然 ASCII 文件是二进制文件,但有些人把它们当作 不同种类的文件。我喜欢将 ASCII 文件视为特殊文件 各种二进制文件。它们是写入每个字节的二进制文件 ASCII码。

      完整的通用二进制文件没有这样的限制。 256 个中的任何一个 位模式可用于二进制文件的任何字节。

      我们一直在处理二进制文件。可执行文件、目标文件、 图像文件、声音文件和许多文件格式都是二进制文件。什么 使它们成为二进制仅仅是二进制文件的每个字节 可以是 256 位模式之一。它们不限于 ASCII 代码。

      【讨论】:

      • 非常感谢格兰特!但是你能解释一下我在读取任何文件时应该记住什么吗,你能告诉我如何读取位图图像的第一个像素(而不是绘制像素) 我知道它可以通过使用 seekg() 搜索到 56 个字节并将其加载到内存中来提取,但是我怎样才能像其他程序一样将这些值加载到内存中,就像大多数二进制文件 i/o 教程一样,只需提取任何字符串从文件中提取并显示它,而他们从不使用 seekg() 来寻求...。请帮助我并感谢您的回答!它真的对我有帮助......
      • 通常你一次读取一个文件的一个块。如果你知道块的格式——比如位图——那么你可以定义一个包含位图的“struct”或“typedef struct”,并在一个“fread”语句中简单地读取整个“struct”(也许你需要“ fseek´ 到文件中的正确位置)。 'fread' 是连续的,因为它从它停止读取的最后一个位置开始读取 - 除非你 'fseek' 到另一个位置。 (这些是 C 函数,但它们在 C++ 中的工作方式相同)
      • 谢谢你!再次换一个新词“chunks”/ 使用 struct 来读取这些块,感谢您的帮助...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-25
      • 2022-12-21
      • 2013-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多