Как мне проверить, что NSData - это PDF? - PullRequest
5 голосов
/ 29 сентября 2010

При работе с приложением iPhone для чтения каналов, которое отображает nsdata (html и pdf) в UIWebView.Я попал в ловушку какой-то логики проверки PDF.У меня есть объект NSData, который, как я знаю, содержит файл с расширением .pdf.Я хотел бы ограничить получение недействительных PDF-файлов дальше.Вот моя первая попытка проверки кода, которая работает в большинстве случаев:

// pdfData is an NSData *
NSData *validPDF = [[NSString stringWithString:@"%PDF"] dataUsingEncoding: NSASCIIStringEncoding];
if (!(pdfData && [[pdfData subdataWithRange:NSMakeRange(0, 4)] isEqualToData:validPDF])) {
    // error
}

К сожалению, новый PDF-файл был загружен несколько дней назад.Он действителен в том смысле, что UIWebView будет отображать его нормально, но он не прошел мой тест проверки.Я проследил проблему до того факта, что в начале это была куча мусорных байтов, когда% PDF шел посередине 14-го набора шестнадцатеричных символов (25 или% - это точно 54-й байт):

%PDF: 25504446
Breaking PDF: 00010000 00ffffff ff010000 00000000 000f0100 0000b5e0 04000200 01000000 ffffffff 01000000 00000000 0f010000 0099e004 00022550 44462d31 etc...

Каков наилучший способ проверки NSData в виде PDF?Что может быть не так с этим конкретным PDF (он утверждает, что он был закодирован PaperPort 11.0, что бы это ни было)?

Спасибо,

Майк

Ответы [ 5 ]

4 голосов
/ 17 апреля 2017
let fileManager = FileManager()
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    let rootDirectory = "\(documentsPath)/\(caption!)/"
    let imageURL = URL(fileURLWithPath: rootDirectory).appendingPathComponent("0")
    let ns = NSData(contentsOf: imageURL)
    let fileExists = fileManager.fileExists(atPath: imageURL.path)
    var isPDF:Bool = false
    if (ns?.length)! >= 1024 //only check if bigger
    {
        var pdfBytes = [UInt8]()
        pdfBytes = [ 0x25, 0x50, 0x44, 0x46]
        let pdfHeader = NSData(bytes: pdfBytes, length: 4)
        let a = ns?.range(of: pdfHeader as Data, options: .anchored, in: NSMakeRange(0, 1024))
        if (a?.length)! > 0
        {
            isPDF = true


        }
        else
        {
            isPDF = false

        }
    }
4 голосов
/ 29 сентября 2010

Этот вопрос кажется весьма полезным:

Определите, правильный ли файл PDF (заголовок PDF)

или, если вы любите приключения, вотспецификация (с сайта Adobe здесь )

3 голосов
/ 28 апреля 2016

Может быть попробовать это ..

    // Validate PDF using NSData
    - (BOOL)isValidePDF:(NSData *)pdfData {
        BOOL isPDF = false;
        if (pdfData.length >= 1024 ) {

            int startMetaCount = 4, endMetaCount = 5;
            // check pdf data is the NSData with embedded %PDF & %%EOF
            NSData *startPDFData = [NSData dataWithBytes:"%PDF" length:startMetaCount];
            NSData *endPDFData = [NSData dataWithBytes:"%%EOF" length:endMetaCount];
            // startPDFData, endPDFData data are the NSData with embedded in pdfData
            NSRange startRange = [pdfData rangeOfData:startPDFData options:0 range:NSMakeRange(0, 1024)];
            NSRange endRange = [pdfData rangeOfData:endPDFData options:0 range:NSMakeRange(0, pdfData.length)];

            if (startRange.location != NSNotFound && startRange.length == startMetaCount && endRange.location != NSNotFound && endRange.length == endMetaCount ) {
                // This assumes the start & end PDFData doesn't have a specific range in file pdf data
                isPDF = true;

            } else  {
                isPDF = false;
            }
        }
        return isPDF;
    }
3 голосов
/ 30 марта 2015

В Swift у меня есть следующее:

var isPDF:Bool = false
if assetData.length >= 1024 //only check if bigger
{
    var pdfBytes = [UInt8]()
    pdfBytes = [ 0x25, 0x50, 0x44, 0x46]
    let pdfHeader = NSData(bytes: pdfBytes, length: 4)
    let foundRange = assetData.rangeOfData(pdfHeader, options: nil, range: NSMakeRange(0, 1024))
    if foundRange.length > 0
    {
        isPDF = true
    }
}
1 голос
/ 11 июня 2018

Свифт 4

extension Data {
    var isPDF: Bool {
        guard self.count >= 1024 else { return false }
        let pdfHeader = Data(bytes: "%PDF", count: 4)
        return self.range(of: pdfHeader, options: [], in: Range(NSRange(location: 0, length: 1024))) != nil
    }
}
...