Я работаю над типом приложения для обработки файлов. Недавно я столкнулся с ошибкой, вызванной ссылками, которые не имеют расширения файла, подобного этому :Как отличить, если 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;
}
Попробуйте [libmagic] (https://github.com/threatstack/libmagic). –
Если это HTTP-запрос, тогда сервер установит 'content-type' в ответе HTTP. Вы не можете это использовать? – trojanfoe
Если нет других доступных подсказок, попробуйте разобрать как XML и перейти на не-XML при ошибке. –