c语言 - 是否可以将文本文件作为二进制文件读取



我正在研究GLSL着色器程序加载器。着色器程序只是包含源代码的纯文本。我可以通过在二进制模式下调用fopen()来打开它们,这要容易得多。但是由于我的源文件是文本,我应该正确使用fopen()来处理没有二进制标志的文本文件并逐行读取它们吗?逐行连接整个文本更乏味,并且行缓冲区长度被fgets()读取上限。因此,如果有任何行长于缓冲区,则读取将失败。但是程序...顺便说一下,它们是文本文件...在二进制模式下读取文本文件的缺点是什么?可能会出现编码或行尾问题?我该怎么办?我应该以二进制模式还是文本模式阅读它们?

在文本模式下读取文本文件的缺点。

  • 跨平台使用。

其本机平台中的文本文件在文本模式下打开效果很好。 然而,如果"n"文件在"rn"系统中被读取,跨平台工作很容易中断文件处理 - 反之亦然。

为了很好地处理这种文本文件变体,我们需要测试至少4 个条件:

  • "n"文件在"n"系统中读取。
  • "n"文件在"rn"系统中读取。
  • "rn"文件在"n"系统中读取。
  • "rn"文件在"rn"系统中读取。

如果文件被读取为二进制文件,我们担心的情况数量减少一半,即 2,因此具有测试优势。

  • "n"文件。
  • "rn"文件。

我们可以用fgets()读取上述 2 种情况下的一,然后用通用代码删除潜在的行尾:

buf[strcspn(buf, "nr")] = '';

然而,这就够了吗?

这并不是真正的,因为一些旧系统已经知道使用'r'作为生产线的末端。在这种情况下,上面的代码是不够的,因为fgets()找不到'n'

上面的代码还假定除了行尾之外'r'不会出现。

其他注意事项

  • 前导字节可以是字节顺序标记。

  • 最后一个字节可能是CtrlZ,并不是文本的一部分。

  • 行尾可能是"n""rn""r"或其他的混合,因为混合历史编辑假定了某个结尾。

  • 最后一行可能/可能不会以适当的行尾字符结尾。

  • 窄字符与宽字符。

  • 未来:通过以文本模式打开,我们依靠当前系统来处理当前的文本文件格式,而不仅仅是我们在编写代码时所知道的格式。

<小时 />

底线

  • 除非可以跨平台使用,否则请使用文本模式。

  • 否则,对文本文件
  • 使用二进制模式,并准备好处理许多文本文件标准。 (IMO:这意味着至少将文件的一部分读取为二进制文件,分析它是什么类型的文本文件,然后继续制作文本处理或以文本模式重新打开作为后备情况。

fopenbinary/text标志只是关于换行转换。binary只是按原样通过换行符,text会将运行程序的操作系统通用的换行符序列转换为简单n单字节换行符。GLSL编译器根本不关心它看到的是什么样的换行符(Unix风格的n,Windows/DOS风格的rn,RISC OS风格的nr),无论如何,它都是空格。

也没有必要用分割线呈现OpenGL。glShaderSource采用字符串数组是为了方便起见,以便您可以拥有一些常见的着色器字符串,将其作为标头或类似内容放入源字符串向量中。但是只提供一根长字符串是完全可以的。

如果要将文件作为行处理,则应以文本模式打开该文件。文本模式会自动将操作系统的换行符转换为n。所以在Windows上,rn序列将被转换为nfgets()将使用rn作为行分隔符;在Unix上,换行符已经n,所以不需要翻译,二进制和文本模式之间没有区别。

我看到的是"适合专家的东西不适合新手"。 如果您想继续,这是您的路径:

  • 被告知"否">
  • 尝试去做
  • 了解为什么不
  • 适应
  • 学习
  • 开发作为输入库镜像的库
  • 发现"否"已成为"是"。

还是只是复制文件?如果是这样,没问题。打开并复制掉。

在过去,我们有关于文本文件的事情;你得到了你的平台在打开它们时的行为,当在系统之间复制文件时,你必须转换行尾。

那些日子正在逝去;每个人都放弃了文本模式下的fopen,只使用简单的状态机接受任何行尾。