2015-08-10 2 views
2

Я работаю над типом приложения для обработки файлов. Недавно я столкнулся с ошибкой, вызванной ссылками, которые не имеют расширения файла, подобного этому :Как отличить, если NSData является xls, ppt или doc на объекте c

https://drive.google.com/uc?export=download&id=1234567abcdefghijk 

Я основывая тип файла по имени файла, расположенного на конце линии, которая является прямой ссылкой на файл.

В случае перенаправляющей ссылки, такой как ссылка на привод Google выше, она по-прежнему возвращает данные, но проблема в том, что у нее нет расширения файла, UIWebView не отображает типы файлов документа (I используйте другой просмотрщик для типов изображений, и он выглядит довольно хорошо, потому что вы можете передавать данные непосредственно на UIImage).

Решение, с которым я столкнулся, состояло в том, чтобы проверить на Подпись файла, которую вы можете найти в первых 1024 байтах данных. Я нашел файловые подписи для типов документов в http://www.filesignatures.net/index.php.

Я могу различать изображения и типы файлов PDF, но проблема заключается в xls/ppt/doc и xlsx/pptx/docx, потому что они имеют одинаковые подписи файлов, [D0 CF 11 E0 A1 B1 1A E1] и [50 4B 03 04] соответственно.

Теперь я хочу знать, есть ли другие способы дифференцировать файлы документов Microsoft Office.

Это код, который я уже сделал, если вы знаете, как улучшить эту функцию, я бы принял его с некоторыми пояснениями:

typedef enum FileSignature { 
    kFileSignaturePDF, 
    kFileSignaturePPT_DOC_XLS, 
    kFileSignaturePPTX_DOCX_XLSX, 
    kFileSignaturePNG, 
    kFileSignatureJPG, 
    kFileSignatureBMP, 
    kFileSignatureUndefined, 
}FileSignature; 

+ (FileSignature) getDocumentTypeOfData:(NSData *)documentData { 

    if (documentData.length >= 1024) { 
     const unsigned char pdfBytes[] = {0x25, 0x50, 0x44, 0x46}; 
     const unsigned char jpgBytes[] = {0xFF, 0xD8, 0xFF, 0xE0}; 
     const unsigned char pngBytes[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; 
     const unsigned char bmpBytes[] = {0x42, 0x4D}; 
     // pptx,xlsx,docx 
     const unsigned char msOfficeXBytes[] = {0x50, 0x4B, 0x03, 0x04}; 
     // ppt,xls,doc 
     const unsigned char msOfficeBytes[] = {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}; 

     NSString *pdfByteString = [[NSString alloc] initWithBytes:pdfBytes length:sizeof(pdfBytes) encoding:NSASCIIStringEncoding]; 
     NSString *jpgByteString = [[NSString alloc] initWithBytes:jpgBytes length:sizeof(jpgBytes) encoding:NSASCIIStringEncoding]; 
     NSString *pngByteString = [[NSString alloc] initWithBytes:pngBytes length:sizeof(pngBytes) encoding:NSASCIIStringEncoding]; 
     NSString *bmpByteString = [[NSString alloc] initWithBytes:bmpBytes length:sizeof(bmpBytes) encoding:NSASCIIStringEncoding]; 
     NSString *msOfficeXByteString = [[NSString alloc] initWithBytes:msOfficeXBytes length:sizeof(msOfficeXBytes) encoding:NSASCIIStringEncoding]; 
     NSString *msOfficeByteString = [[NSString alloc] initWithBytes:msOfficeBytes length:sizeof(msOfficeBytes) encoding:NSASCIIStringEncoding]; 

     NSArray *arrayOfBytesToSearchFor = [[NSArray alloc] initWithObjects:pdfByteString,jpgByteString,pngByteString,bmpByteString, msOfficeByteString, msOfficeXByteString, nil]; 

     NSString *foundByteString = NULL; 

     for (NSString *byteString in arrayOfBytesToSearchFor) { 
      const unsigned char *searchForByte = (const unsigned char *) [byteString cStringUsingEncoding:NSASCIIStringEncoding]; 

      NSData *searchForByteData = [NSData dataWithBytes:searchForByte length:sizeof(searchForByte)]; 
      NSRange foundRange = [documentData rangeOfData:searchForByteData options:NSDataSearchAnchored range:NSMakeRange(0, 1024)]; 

      if (foundRange.length > 0) { 
       foundByteString = byteString; 
       break; 
      } 
     } 

     FileSignature fileType = kFileSignatureUndefined; 

     int indexOfFoundByteString = [arrayOfBytesToSearchFor indexOfObject:foundByteString]; 

     switch (indexOfFoundByteString) { 
      case 0: 
       fileType = kFileSignaturePDF; 
       break; 
      case 1: 
       fileType = kFileSignatureJPG; 
       break; 
      case 2: 
       fileType = kFileSignaturePNG; 
       break; 
      case 3: 
       fileType = kFileSignatureBMP; 
       break; 
      case 4: 
       fileType = kFileSignaturePPT_DOC_XLS; 
       break; 
      case 5: 
       fileType = kFileSignaturePPTX_DOCX_XLSX; 
       break; 
      default: 
       fileType = kFileSignatureUndefined; 
       break; 
     } 

     return fileType; 
    } 

    return kFileSignatureUndefined; 
} 
+1

Попробуйте [libmagic] (https://github.com/threatstack/libmagic). –

+1

Если это HTTP-запрос, тогда сервер установит 'content-type' в ответе HTTP. Вы не можете это использовать? – trojanfoe

+1

Если нет других доступных подсказок, попробуйте разобрать как XML и перейти на не-XML при ошибке. –

ответ

0

мне потребовалось некоторое время, чтобы отправить это, но Я пошел по идее трояна по поводу получения content-type в заголовке ответа, если вы используете AFNetworking 2.0, а затем на блоке успеха вы можете получить контент-тип operation.response.allHeaderFields, allHeaderFields также является собственностью NSHTTPURLResponse для тех, кто делает руководство NSURLConnection способ.

Если вы можете сделать некоторые улучшения в этом, будь то оптимизация или меньшая строка кода или дополнений в списке поддерживаемых документов, я предлагаю вам отправить ответ.

typedef enum DocumentType { 
    kDocumentTypePDF, 
    kDocumentTypePPT, 
    kDocumentTypeDOC, 
    kDocumentTypeXLS, 
    kDocumentTypePPTX, 
    kDocumentTypeDOCX, 
    kDocumentTypeXLSX, 
    kDocumentTypePNG, 
    kDocumentTypeJPG, 
    kDocumentTypeBMP, 
    kDocumentTypeIMG, 
    kDocumentTypeUndefined, 
}DocumentType; 

+ (DocumentType) getDocumentTypeBasedOnContentType:(NSString *)contentType { 

    if ([contentType isEqualToString:@"application/pdf"]) { 
     return kDocumentTypePDF; 
    } else if ([contentType isEqualToString:@"application/mspowerpoint"] || 
       [contentType isEqualToString:@"application/powerpoint"] || 
       [contentType isEqualToString:@"application/vnd.ms-powerpoint"] || 
       [contentType isEqualToString:@"application/x-mspowerpoint"]) { 
     return kDocumentTypePPT; 
    } else if ([contentType isEqualToString:@"application/msword"]) { 
     return kDocumentTypeDOC; 
    } else if ([contentType isEqualToString:@"application/excel"] || 
       [contentType isEqualToString:@"application/vnd.ms-excel"] || 
       [contentType isEqualToString:@"application/x-excel"] || 
       [contentType isEqualToString:@"application/x-msexcel"]) { 
     return kDocumentTypeXLS; 
    } else if ([contentType isEqualToString:@"application/vnd.openxmlformats-officedocument.wordprocessingml.document"]) { 
     return kDocumentTypeDOCX; 
    } else if ([contentType isEqualToString:@"application/vnd.openxmlformats-officedocument.presentationml.presentation"]) { 
     return kDocumentTypePPTX; 
    } else if ([contentType isEqualToString:@"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]) { 
     return kDocumentTypeXLSX; 
    } else if ([contentType rangeOfString:@"image/"].location != NSNotFound) { 
     return kDocumentTypeIMG; 
    } else { 
     return kDocumentTypeUndefined; 
    } 

} 
Смежные вопросы