请容忍我,因为我在不知道所有背景的情况下被扔进了这个项目的中间。如果你有任何问题,相信我,我也有。
场景是这样的:我有一堆文件驻留在IIS服务器上。它们上面没有文件扩展名。只是像"asda-2342-sd3rs-asd24-ut57“之类的裸文件。没有什么直观的东西。
问题是我需要在ASP.NET (2.0)页面上提供文件,并将tiff文件显示为tiff,将PDF文件显示为PDF。不幸的是,我不知道哪一个是哪一个,我需要能够以它们各自的格式适当地显示它们。
例如,假设我需要显示两个文件,一个是tiff文件,一个是PDF文件。页面应该显示一个tiff图像,也许还有一个在新选项卡/窗口中打开PDF的链接。
问题是:
由于这些文件都是无扩展名的,我不得不强制
将所有内容都作为TIFF提供服务。但如果我这样做,PDF文件将不会显示。对于未知的文件扩展名,我可以更改IIS以强制MIME类型为PDF,但我会遇到相反的问题。
http://support.microsoft.com/kb/326965
这个问题是比我想象的简单,还是像我预期的那样糟糕?
发布于 2010-04-29 02:20:35
好了,有足够多的人搞错了,所以我要发布一些代码来识别TIFF:
private const int kTiffTagLength = 12;
private const int kHeaderSize = 2;
private const int kMinimumTiffSize = 8;
private const byte kIntelMark = 0x49;
private const byte kMotorolaMark = 0x4d;
private const ushort kTiffMagicNumber = 42;
private bool IsTiff(Stream stm)
{
stm.Seek(0);
if (stm.Length < kMinimumTiffSize)
return false;
byte[] header = new byte[kHeaderSize];
stm.Read(header, 0, header.Length);
if (header[0] != header[1] || (header[0] != kIntelMark && header[0] != kMotorolaMark))
return false;
bool isIntel = header[0] == kIntelMark;
ushort magicNumber = ReadShort(stm, isIntel);
if (magicNumber != kTiffMagicNumber)
return false;
return true;
}
private ushort ReadShort(Stream stm, bool isIntel)
{
byte[] b = new byte[2];
_stm.Read(b, 0, b.Length);
return ToShort(_isIntel, b[0], b[1]);
}
private static ushort ToShort(bool isIntel, byte b0, byte b1)
{
if (isIntel)
{
return (ushort)(((int)b1 << 8) | (int)b0);
}
else
{
return (ushort)(((int)b0 << 8) | (int)b1);
}
}
我破解了一些更通用的代码来得到这个。
对于PDF,我有如下代码:
public bool IsPdf(Stream stm)
{
stm.Seek(0, SeekOrigin.Begin);
PdfToken token;
while ((token = GetToken(stm)) != null)
{
if (token.TokenType == MLPdfTokenType.Comment)
{
if (token.Text.StartsWith("%PDF-1."))
return true;
}
if (stm.Position > 1024)
break;
}
return false;
}
现在,GetToken()是对扫描器的调用,它将流标记为PDF标记。这不是无关紧要的,所以我不打算在这里粘贴它。我使用记号赋予器而不是子字符串来避免类似这样的问题:
% the following is a PostScript file, NOT a PDF file
% you'll note that in our previous version, it started with %PDF-1.3,
% incorrectly marking it as a PDF
%
clippath stroke showpage
上面的代码片段将此代码标记为不是PDF,而更简单的代码块将错误地将其标记为PDF。
我还应该指出,当前的ISO规范缺少以前Adobe拥有的规范中的实现说明。最重要的是,来自PDF参考1.6版:
Acrobat viewers require only that the header appear somewhere within
the first 1024 bytes of the file.
发布于 2010-04-29 01:55:43
TIFF可以通过在第一个字节http://local.wasp.uwa.edu.au/~pbourke/dataformats/tiff/处窥视来检测
头8个字节形成报头。它的前两个字节或者是"II“表示小端字节排序,或者是"MM”表示大端字节排序。
关于http://www.adobe.com/devnet/livecycle/articles/lc_pdf_overview_format.pdf
标题只包含一行标识
版本的内容。示例:%PDF-1.6
发布于 2010-04-29 02:08:00
阅读每种文件格式的规范将告诉您如何识别该格式的文件。
TIFF文件-检查字节1和2的0x4D4D或0x4949,检查字节2-3的值'42‘。
规范的第13页写道:
TIFF文件以8字节的图像文件头开始,包含以下信息:字节0-1:文件中使用的字节顺序。合法值为:“II”(4949.H)“MM”(4D4D.H)在“II”格式中,字节顺序始终是从最低有效字节到最高有效字节,对于16位和32位整数,这称为小端字节顺序。在“MM”格式中,对于16位和32位整数,字节顺序总是从最高有效位到最低有效位。这称为big-endian字节顺序。字节2-3是一个任意但仔细选择的数字(42),它进一步将文件标识为TIFF文件。字节顺序取决于字节0-1的值。
PDF文件以PDF版本开头,后跟几个二进制字节。(我认为您现在必须购买当前版本的ISO规范。)
第7.5.2节
文件的第一行应是由5个字符组成的标头% PDF -,后跟格式为1.N的版本号,其中N是介于0和7之间的数字。符合要求的阅读器应接受具有以下任何标头的文件:%PDF-1.0、%PDF-1.1、%PDF-1.2、%PDF-1.3、%PDF-1.4、%PDF-1.5、%PDF-1.6、% PDF -1.7从PDF 1.4开始,应使用文档目录字典中的版本条目(通过文件尾部中的根条目,如7.5.5,“文件尾部”中所述),如果存在,则应使用该版本条目,而不是标题中指定的版本。
如果PDF文件像大多数文件一样包含二进制数据(请参阅7.2,“词汇约定”),则标题行后面应紧跟一个注释行,其中至少包含四个二进制字符,即代码为128或更大的字符。这确保了文件传输应用程序的正确行为,这些应用程序检查文件开头附近的数据,以确定是将文件内容视为文本还是二进制。
当然,您可以通过检查更多特定于文件的项来对每个文件进行“更深层次”的检查。
https://stackoverflow.com/questions/2731917
复制相似问题