【问题标题】:Reading text from binary file like PDF从二进制文件(如 PDF)中读取文本
【发布时间】:2013-02-23 16:43:20
【问题描述】:

我在读取 C++ 中的二进制文件时遇到问题。目前我的代码是这样的:

FILE *s=fopen(source, "rb");
fseek(s,0,SEEK_END);
size_file size=ftell(s);
rewind(s);

char *sbuffer=(char *) malloc(sizeof(char) * size);
if(sbuffer==NULL){
    fputs("Memory error", stderr);
    exit(2);
}
size_t result=fread(sbuffer,1,size,s);
if(result != size){
    fputs("Reading error",stderr);
    exit(3);
}
fclose(s);
cout<<sbuffer<<endl;

但是,终端打印出来的字符都是随机字符,而不是我在PDF文件中写的。他们是这样的:

% P D F - 1 . 3 
 % ? ? ? ? ? ? ? ? ? ? ? 
 4   0   o b j 
 < <   / L e n g t h   5   0   R   / F i l t e r   / F l a t e D e c o d e   > > 
 s t r e a m 
 x  ? ? ? j ? 0  E ? ? ? k ?  y Q E # ? ? ? m ? & ? ? @  % + ? .     ? ?  ? ? A i  ?     4 z \ 1 G W ? ?  - , ? ? ? (  ? ? ?  9 ? ? ? ? ?  \ ? } ? ? ? e ? ? ? ? 0 ? ? ? ~ ? , ? ? & 8 ? ? x e 4 ? r 
 | ? ? ? 
          ? ? ? ? E  > a ? ? z & ? Z ? < ?  }  '  ? ? ? j p ? ? Q 7 0 ? ? ? S %  - p ? ? ? 7 D  ?  ? ? ' Q z Q ?  ? ? ? ? ? ? ? ? ? \ 2 ? ? 7 ? ? ? < ? ? D ~  ? ? ? 

 e n d s t r e a m 
 e n d o b j 
 5   0   o b j 
 2 2 8 
 e n d o b j 
 2   0   o b j

还有许多其他类似上述的角色。我试图搜索很长时间,但无法找到如何获取实际字符以供以后处理。顺便说一句,我正在尝试编写一个以二进制文件作为输入和输出的压缩器。非常感谢这里的任何帮助!

【问题讨论】:

  • 您的代码没有进行任何打印!怎么回事?!
  • 我用 'cout
  • 如果您要打印带有格式化输出的任意数据,那您的日子会很糟糕。
  • 投票以“按预期工作”结束。
  • 你在开玩笑吧?您希望您可以读取二进制 PDF 文件,而 C++ 会以某种方式神奇地为您解码?在十六进制编辑器中弹出您的 PDF。我相信你会看到你的程序打印出正确的东西。

标签: c++ file-io


【解决方案1】:

只有少数文件格式,如纯原始 .TXT 文本文件可以直接“读取”和“理解”。大多数文件格式,包括几乎所有二进制格式,都是.. 格式。这意味着文件中包含某些结构。与.TXT 文本文件完全相反,它完全没有结构,或者更确切地说,它是一大块纯数据。

打开写字板或 Word 或任何其他至少有点智能文本编辑器并在那里写一些文本,然后将其保存为 RTF、DOC、ODT 或任何其他非 TXT 文件。然后也保存为TXT文件。

下载 HEX VIEWER/HEX EDITOR。随便一个。拿其中一个免费的,你不需要很多功能,只需要一个在一列中显示原始二进制值,在另一列中显示 ASCII 文本的功能。几乎所有免费的十六进制查看器/编辑器都可以做到这一点。

打开并比较这两个文件。您会立即看到不同之处。

返回 PDF:

PDF 甚至可以包含与文本交错的图形。如果文本像在 TXT 中一样“只是坐在文件中”,您希望如何保留它?如何嵌入图像位置/描述/数据?如果我没记错的话,PDF 甚至可以包含类似于 JavaScript 的脚本。可执行。在 PDF 类型的文档中,您可以拥有执行某些操作的按钮。这比在文件中输入文本要复杂得多。

二进制文件通常不包含任何可读的文本。他们将文本以块的形式结构化,包裹在关于颜色、文本布局、分页等的元数据中,甚至包含关于文档版本控制、创作、分类等的特殊结构(...)。这一切都必须存储在某个地方。

通常,二进制文件有部分。第一部分通常称为 HEADER。在里面,会有以下信息:格式类型、格式版本、文件/块/数据长度、图像分辨率等。所有这些最有可能以二进制形式保存:没有“800x600”文本,只有“|00|00|03|20|00|00|02|58|”假设 32 位 BE。在你阅读、解码和理解描述之后,你就会知道实际数据从哪里开始,数据块是如何布局的,以及如何解码它们并理解它们包含的内容。

编辑:

在您了解文本文件和二进制文件之间的区别后,请查看http://en.wikipedia.org/wiki/Entropy_(information_theory) 的绝对基础知识。然后尝试使用 RLE (http://www.daniweb.com/software-development/cpp/code/216388/basic-rle-file-compression-routine) 或 Huffman (http://www.cprogramming.com/tutorial/computersciencetheory/huffman.html) 来开始一些相对简单的事情。然后开始阅读有关 Huffman 代码的更多信息,然后,你将为这项任务做好充分的准备,例如 ZIP 或 LZH..

【讨论】:

  • 如果您真的很喜欢压缩主题,我提供了一些起点的链接。玩得开心!
  • 我正在尝试实现 LZ77 算法,因此我尝试查看每个单独的字符......非常感谢!
  • 为了简单起见,不用看字符,只看数据的原始字节。无论您分析由字符 0..9a..zA..Z!@#$%^&* 组成的文本流,还是分析字节流 00/01/02/03/,都几乎没有区别。 ../FE/FF。输入时不是半随机的〜80个符号,而是半随机的256个符号:)
  • 是的..目前我使用 forloop 来获取 sbuffer[i] 并尝试查找在以前的上下文中是否有任何重复,如 LZ77 算法所述。这是在查看数据的原始字节吗?如果不是,那么要实现压缩器,我还需要将 PDF 解析为文本字符吗?非常感谢...
  • 是的,当使用带有rb 标志的fopen 时,fread 从文件中读取原始字节,而不进行任何翻译。您的缓冲区将包含与磁盘上的文件完全相同的内容。要压缩文件,您不需要解析它。如果发布了一些新版本的文件,这通常会太复杂和/或太冒险。 > 90% 的压缩器只是将文件压缩为一大块字节,而忽略文件格式。在某些情况下,确实会更彻底地分析文件,但很少见,通常将其称为“压缩格式”而不是“压缩文件”,即 Flash FWS 与 CWS。
【解决方案2】:

要将 PDF 解析为文本,请使用一些 PDF 库,例如 gnupdfpoppler.

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    • 2018-11-19
    • 2018-08-24
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多