我有一个视觉基础程序,可以从Internet下载单个文件。这些文件可以是PDF,也可以是实际的网页,也可以是文本。通常,我不会碰到任何其他类型的文件(也许图像除外)。 似乎很容易知道我要下载的文件类型,只需测试URL的扩展名即可。
例如,诸如“ http://microsoft.com/HowToUseAzure.pdf”之类的URL可能是PDF。但是有些URL看起来不是这样。我遇到了一个看起来像这样的东西:
http://www.sciencedirect.com/science?_ob=MImg& _imagekey=B6VMC-4286N5V-6-18& _cdi=6147& _orig=search& _coverDate=12%2F01%2F2000& _qd=1& _sk=999059994& wchp=dGLSzV-lSzBV& _acct=C000000152& _version=1& _userid=4429& md5=d4d53f46bdf6fb8c7431f4a2e04876e7& ie=f.pdf
我可以对此URL进行一些智能解析,最后我得到了第一部分:
http://www.sciencedirect.com/science
和第二部分,问号及其后的所有内容。在这种情况下,尽管第二部分确实有线索,但第一部分没有告诉我我拥有哪种类型的文件。但是第二部分可能是任意的。所以我的问题是,在这种情况下我该怎么办?我可以将文件下载为“二进制”文件,然后测试“二进制”字节,看看是否有
1)文字2)pdf 3)html?
如果是,测试是什么?无论如何,“ binary”和“ pdf”以及“ text”之间有什么区别?二进制文件中是否存在一些字节值,而这些值根本不会出现在html文件,Unicode文件或pdf文件中? / p>
谢谢。
答案 0 :(得分:1)
允许我引用ISO 32000-1:
PDF文件的第一行应为标头,由5个字符组成,%PDF–后跟版本号为1.N,其中N为0到7之间的数字。
和ISO 32000-2:
PDF文件以5个字符“%PDF–”开头,偏移量应从PERCENT SIGN(25h)开始计算。
有什么区别?当遇到以%PDF-1.0
至%PDF-1.7
开头的文件时,您有一个ISO 32000-1文件。从ISO 32000-2开始,PDF文件也可以从%PDF-2.0
开始。
ISO 32000也对此进行了解释:
如果PDF文件像大多数情况一样包含二进制数据,则标题行应紧跟在注释行之后,该注释行至少包含四个二进制字符,即,代码为128或更大的字符。这样可以确保文件传输应用程序的正常行为,该应用程序可以检查文件开头附近的数据,以确定是将文件内容视为文本还是二进制。
如果在文本编辑器中而不是在PDF查看器中打开PDF,通常会看到第二行如下所示:
%âãÏÓ
没有“纯文本文件”之类的东西;文件始终具有编码。但是,当人们谈论纯文本文件时,通常是指ASCII文件。 ASCII文件是其所有字节的值都小于128(10000000
)的文件。
在过去,传输协议通常将PDF文档视为ASCII文件。他们没有发送8位字节,而是仅发送了每个字节的前7位(有时称为“字节剃除”)。发生这种情况时,会保留PDF文件的ASCII字节,但所有二进制内容都会损坏。在PDF查看器中打开此类PDF时,您会看到PDF文件的页面,但每个页面都是空的。
为避免此问题,在PDF标头中添加了四个非ASCII字符。传输协议检查第一个字节系列,发现其中一些字节的值大于127(01111111
),因此将该文件视为二进制文件。
这比较棘手,因为HTML允许人们草率行事。您可能希望HTML文件的第一个非空白字符为<
字符,但是这样的文件也可以是非HTML格式的简单XML文件。
您期望<!doctype html>
,<html>
或<body>
在文件中的某个位置(标签内带有或不带有属性),但是有些人创建HTML文件时没有提到DocType,并且即使没有<html>
或<body>
标签也是如此。
请注意,HTML文件可以采用许多不同的编码。例如:当使用UTF-8编码时,它们将包含值大于127的字节。
仅循环遍历所有字节。如果找到的字节值大于127,则说明文件不是ASCII格式。
在这种情况下,将有一个字节顺序标记(BOM),使您可以检测文件的编码。详细了解该here。
当然有!例如参见ISO/IEC 8859。在许多情况下,文本文件不知道使用哪种编码,因为该编码没有存储为文件的属性。