2010-04-28 4 views
16

कृपया मेरे साथ सहन करें क्योंकि मुझे इस परियोजना के मध्य में सभी पृष्ठभूमि जानने के बिना फेंक दिया गया है। यदि आपके पास डब्ल्यूटीएफ प्रश्न हैं, तो मेरा विश्वास करो, मेरे पास भी है।यह पता लगाने के लिए कि कोई फ़ाइल पीडीएफ या टीआईएफएफ है या नहीं?

यहां परिदृश्य है: मुझे आईआईएस सर्वर पर रहने वाली फाइलों का एक गुच्छा मिला है। उनके पास उनके पास कोई फ़ाइल एक्सटेंशन नहीं है। "Asda-2342-sd3rs-asd24-ut57" जैसे नामों के साथ बस नग्न फ़ाइलें और इसी तरह। कुछ सहज नहीं है।

समस्या यह है कि मुझे एएसपी.NET (2.0) पृष्ठ पर फ़ाइलों को प्रस्तुत करने की आवश्यकता है और टिफ़ फ़ाइलों को टिफ़ और पीडीएफ फाइलों को पीडीएफ के रूप में प्रदर्शित करना है। दुर्भाग्य से मुझे नहीं पता कि कौन सा है और मुझे उन्हें अपने संबंधित प्रारूपों में उचित रूप से प्रदर्शित करने में सक्षम होना चाहिए।

उदाहरण के लिए, मान लें कि 2 फाइलें हैं जिन्हें मुझे प्रदर्शित करने की ज़रूरत है, एक टिफ है और एक पीडीएफ है। पृष्ठ को एक टिफ छवि के साथ दिखाना चाहिए, और शायद एक लिंक जो एक नए टैब/विंडो में पीडीएफ खोल देगा।

समस्या:

इन फ़ाइलों के रूप में कर रहे हैं सभी एक्सटेंशन-कम मैं तो बस सब कुछ सेवा करने के लिए TIFF के रूप में आईआईएस के लिए मजबूर किया था। लेकिन अगर मैं ऐसा करता हूं, तो पीडीएफ फाइलें प्रदर्शित नहीं होंगी। मैं अज्ञात फ़ाइल एक्सटेंशन के लिए एमआईएम प्रकार को पीडीएफ होने के लिए आईआईएस बदल सकता हूं लेकिन मुझे रिवर्स समस्या होगी।

http://support.microsoft.com/kb/326965

इस समस्या को आसान से मुझे लगता है कि है या यह के रूप में बुरा के रूप में मैं उम्मीद कर रहा हूँ?

उत्तर

19

ठीक है, काफी लोग इस गलत है कि मैं मैं झगड़े की पहचान करनी है कुछ कोड पोस्ट करने के लिए जा रहा हूँ हो रही है:

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); 
    } 
} 

मैं कुछ और अधिक सामान्य कोड के अलावा काट दिया इस पाने के लिए।

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() एक स्कैनर है कि पीडीएफ टोकन में एक स्ट्रीम tokenizes में एक फोन है:

पीडीएफ के लिए, मैं कोड है कि इस तरह दिखता है। यह गैर-तुच्छ है, इसलिए मैं इसे यहां पेस्ट नहीं कर रहा हूं। मैं tokenizer उपयोग कर रहा हूँ बजाय सबस्ट्रिंग को देखने का इस तरह एक समस्या से बचने के लिए:

% 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 

इस कोड को ऊपर कोड स्निपेट से नहीं एक पीडीएफ के रूप में चिह्नित है, जबकि कोड का एक भी अधिक साधारण हिस्सा गलत तरीके से यह प्रतीक होगा एक पीडीएफ के रूप में।

मुझे यह भी इंगित करना चाहिए कि वर्तमान आईएसओ स्पेक कार्यान्वयन नोट्स से रहित है जो पिछले एडोब-स्वामित्व वाले विनिर्देशन में थे। अधिकांश पीडीएफ संदर्भ, संस्करण 1.6 से महत्वपूर्ण बात:

Acrobat viewers require only that the header appear somewhere within 
the first 1024 bytes of the file. 
+0

धन्यवाद! मैं इसे आज रात – eviljack

+0

भयानक देखूंगा, यह काम करता है !! – eviljack

+0

stm.Seek (0); मेरे लिए विफल रहता है, संकलित नहीं करता है। मैं बनाम 2008, नेट 3.5 का उपयोग कर रहा हूँ। – Kiquenet

0

यदि आप here पर जाते हैं, तो आप देखेंगे कि टीआईएफएफ आमतौर पर "जादू संख्या" 0x49 0x49 0x2A 0x00 (कुछ अन्य परिभाषाएं भी दी जाती हैं) से शुरू होती है, जो फ़ाइल के पहले 4 बाइट्स हैं।

तो यह निर्धारित करने के लिए कि फ़ाइल TIFF है या नहीं, बस इन पहले 4 बाइट्स का उपयोग करें।

संपादित करें, यह संभवतः दूसरे तरीके से करना बेहतर है, और पहले पीडीएफ का पता लगाना बेहतर है। पीडीएफ के लिए जादू संख्या अधिक मानकीकृत हैं: प्लिंथ ने कृपया ध्यान दिया कि वे पहले 1024 बाइट्स (0x25 0x50 0x44 0x46) में कहीं भी "% पीडीएफ" से शुरू होते हैं। source

+0

यह जादू संख्याएं छोटे/बड़े एंडियन पर निर्भर करती हैं। – Andrey

+1

यह करीब है, लेकिन गलत है। एक टीआईएफएफ दो हस्ताक्षरों में से एक, 0x49 0x49 0x2a 0x00 या 0x4d 0x4d 0x00 0x2a से शुरू होता है। – plinth

+0

आपकी पीडीएफ जांच भी गलत है। % पीडीएफ केवल पहले 1024 बाइट्स में दिखाई देता है। – plinth

8

TIFF पहले बाइट्स पर देखना http://local.wasp.uwa.edu.au/~pbourke/dataformats/tiff/

पहले 8 बाइट्स हैडर रूपों के द्वारा पता लगाया जा सकता है। पहले दो बाइट्स "II" छोटे एंडियन बाइट ऑर्डरिंग या बड़े एंडियन बाइट ऑर्डरिंग के लिए "एमएम" के लिए है।

पीडीएफ के बारे में: http://www.adobe.com/devnet/livecycle/articles/lc_pdf_overview_format.pdf

हैडर केवल एक पंक्ति है कि पीडीएफ के संस्करण की पहचान होती है। उदाहरण:% पीडीएफ-1.6

+0

एडोब से डॉक्टर काफी सटीक नहीं है। % पीडीएफ-1.x, जहां एक्स एक संख्या है फ़ाइल के पहले 1 के भीतर कहीं भी दिखाई दे सकती है। – plinth

+0

ठीक है, यहां सबसे पूर्ण कल्पना है http://www.adobe.com/devnet/acrobat/pdfs/pdf_reference_1-7.pdf यह है> 30 एमबी – Andrey

2

आंतरिक रूप से, फ़ाइल शीर्षलेख जानकारी को मदद करनी चाहिए। यदि आप निम्न स्तर की फ़ाइल खोलते हैं, जैसे StreamReader() या FOPEN(), फ़ाइल में पहले दो अक्षर देखें ... लगभग हर फ़ाइल प्रकार का अपना हस्ताक्षर होता है।

PDF always starts with "%P" (but more specifically would have like %PDF) 
TIFF appears to start with "II" 
Bitmap files with "BM" 
Executable files with "MZ" 

मैं भी मदद करने के लिए दी गई साइट पर अपलोड होने और तुरंत निरस्त किया जा रहा यह एक बार जाँच की से अवांछित फ़ाइलों को रोकने के अतीत भी इस का सामना करना पड़ा है ...।

संपादित करें - पढ़ने के लिए नमूना कोड और परीक्षण फ़ाइल पोस्ट हैडर प्रकार

String fn = "Example.pdf"; 

StreamReader sr = new StreamReader(fn); 
char[] buf = new char[5]; 
sr.Read(buf, 0, 4); 
sr.Close(); 
String Hdr = buf[0].ToString() 
    + buf[1].ToString() 
    + buf[2].ToString() 
    + buf[3].ToString() 
    + buf[4].ToString(); 

String WhatType; 
if (Hdr.StartsWith("%PDF")) 
    WhatType = "PDF"; 
else if (Hdr.StartsWith("MZ")) 
    WhatType = "EXE or DLL"; 
else if (Hdr.StartsWith("BM")) 
    WhatType = "BMP"; 
else if (Hdr.StartsWith("?_")) 
    WhatType = "HLP (help file)"; 
else if (Hdr.StartsWith("\0\0\1")) 
    WhatType = "Icon (.ico)"; 
else if (Hdr.StartsWith("\0\0\2")) 
    WhatType = "Cursor (.cur)"; 
else 
    WhatType = "Unknown"; 
+0

mr.DRapp, कोई नमूना कोड ?? – Kiquenet

+0

@alhambraeidos - मैंने सी # नमूना – DRapp

+0

के माध्यम से अद्यतन कोड पोस्ट किया है जवाब के महत्वपूर्ण भाग में "शुरू करने के लिए प्रतीत होता है" नहीं होना चाहिए! प्रति spec, टीआईएफएफ फाइलें ASCII "II" या "MM" के 2 बाइट्स के साथ शुरू होती हैं, इसके बाद 2 बाइट (II) इंटेल छोटे-एंडियन, या (एमएम) मोटोरोला बड़े-एंडियन बाइट ऑर्डर, पूर्णांक 42. – Spike0xff

0

आप अनुरोध की गई फ़ाइल प्राप्त करने के लिए एक ashx लिखने के लिए है करने के लिए जा रहे हैं।

तब, आपके हैंडलर को यह निर्धारित करने के लिए पहले कुछ बाइट्स (या तो) को पढ़ना चाहिए कि फ़ाइल प्रकार वास्तव में क्या है - पीडीएफ और टीआईएफएफ के पास फ़ाइल की शुरुआत में "जादू संख्या" है जिसका उपयोग आप इसे निर्धारित करने के लिए कर सकते हैं, फिर तदनुसार अपने प्रतिक्रिया शीर्षलेख सेट करें।

3

एक उर्फ ​​गैरी केसलर द्वारा "जादू संख्या" फाइल हस्ताक्षर का बहुत ही उपयोगी सूची प्रत्येक फ़ाइल स्वरूप के लिए विनिर्देश आपको बता कैसे उस प्रारूप की फ़ाइलों को पहचानने में मदद करेंगे पढ़ना उपलब्ध http://www.garykessler.net/library/file_sigs.html

+0

ए महान लिंक - धन्यवाद! –

4

है।

TIFF फ़ाइलें - 0x4D4D या 0x4949 और बाइट्स मूल्य '42' के लिए 2-3 के लिए बाइट्स 1 और 2 की जाँच करें।

कल्पना की पेज 13 पर लिखा है:

एक TIFF फ़ाइल, एक 8 बाइट छवि फ़ाइल शीर्षक के साथ शुरू होता निम्न जानकारी युक्त बाइट्स 0-1: बाइट फ़ाइल के भीतर इस्तेमाल किया आदेश । कानूनी मान हैं: "II" (4 9 4 9। एच) "एमएम" (4 डी 4 डीएच) "द्वितीय" प्रारूप में, बाइट आदेश कम से कम महत्वपूर्ण बाइट से सबसे अधिक महत्वपूर्ण बाइट से 16 है, दोनों के लिए 16 -bit और 32-बिट पूर्णांक इसे छोटे-एंडियन बाइट ऑर्डर कहा जाता है। "एमएम" प्रारूप में, बाइट ऑर्डर से कम से कम महत्वपूर्ण है, दोनों 16-बिट और 32-बिट पूर्णांक के लिए। यह को बड़े-एंडियन बाइट ऑर्डर कहा जाता है। बाइट्स 2-3 एक मनमानी लेकिन ध्यान से चुने गए संख्या (42) जो फ़ाइल को टीआईएफएफ फ़ाइल के रूप में पहचानता है। बाइट ऑर्डर बाइट्स 0-1 के मान पर निर्भर करता है।

PDF फ़ाइलें पीडीएफ संस्करण के साथ शुरू होती हैं जिसके बाद कई बाइनरी बाइट्स शुरू होते हैं। (मुझे लगता है कि आप अब वर्तमान संस्करण के लिए आईएसओ कल्पना खरीद करने के लिए है।)

धारा 7.5.2

एक PDF फ़ाइल की पहली पंक्ति पात्रों से मिलकर होगा एक हैडर% पीडीएफ- संस्करण के बाद फॉर्म 1. एन, जहां एन 0 और 7 के बीच अंक है। पाठक निम्नलिखित शीर्ष शीर्षकों में से के साथ फ़ाइलों को स्वीकार करेगा:% पीडीएफ-1.0, % पीडीएफ- 1.1,% पीडीएफ-1.2,% पीडीएफ-1.3,% पीडीएफ-1.4, % पीडीएफ-1.5,% पीडीएफ-1.6,% पीडीएफ -17 शुरूपीडीएफ 1 के साथ।4, में दस्तावेज़ प्रविष्टि ( फ़ाइल फ़ाइल ट्रेलर में रूट प्रविष्टि के माध्यम से 7.5.5 में वर्णित अनुसार, "फ़ाइल ट्रेलर"), यदि मौजूद है, तो संस्करण प्रविष्टि के बजाय का उपयोग किया जाएगा हेडर में।

एक PDF फ़ाइल में बाइनरी डेटा है, तो के रूप में सबसे है (7.2, "शाब्दिक सम्मलेन" देखें), शीर्ष लेख पंक्ति तुरंत एक टिप्पणी कम से कम चार बाइनरी युक्त लाइन द्वारा पालन किया जाना जाएगा वर्ण-कि है , जिनके पात्र कोड 128 या अधिक हैं। यह फ़ाइल स्थानांतरण अनुप्रयोगों का उचित व्यवहार सुनिश्चित करता है जो के पास डेटा की जांच निर्धारित करने के लिए फ़ाइल की शुरुआत का निरीक्षण करता है कि फ़ाइल की सामग्री को पाठ या बाइनरी के रूप में उपयोग करना है या नहीं।

बेशक आप अधिक फ़ाइल विशिष्ट वस्तुओं की जांच करके प्रत्येक फ़ाइल पर "गहरी" जांच कर सकते हैं।

+0

कोई नमूना कोड, roygbiv? – Kiquenet

0

आप Myrmec उपयोग कर सकते हैं फ़ाइल प्रकार की पहचान करने, इस लाइब्रेरी फ़ाइल बाइट सिर का उपयोग करें। यह पुस्तकालय nuget "Myrmec" पर उपलब्ध है, और यह रेपो है, myrmec भी माइम प्रकार का समर्थन करता है, आप इसे आजमा सकते हैं। कोड यह पसंद आएगा:

// create a sniffer instance. 
Sniffer sniffer = new Sniffer(); 

// populate with mata data. 
sniffer.Populate(FileTypes.CommonFileTypes); 

// get file head byte, may be 20 bytes enough. 
byte[] fileHead = ReadFileHead(); 

// start match. 
List<string> results = sniffer.Match(fileHead); 

और माइम प्रकार मिलता है:

List<string> result = sniffer.Match(head); 

स्ट्रिंग MIMETYPE = MimeTypes.GetMimeType (result.First());

लेकिन यह समर्थन केवल "49 49 2 ए 00" और "4 डी 4 डी 00 2 ए" दो हस्ताक्षर टिफ, यदि आपके पास और अधिक है, तो आप स्वयं को जोड़ सकते हैं, हो सकता है कि आप मदद के लिए myrmec की रीडेमे फ़ाइल देख सकें। myrmec github repo