How to determine if a zip file is a file?

I need to determine if the file in the application document directory is a zip file. The file name cannot be used when accepting this definition. Therefore, I will need to read the MIME type or find another property that applies only to zip files.

NOTE. A solution that requires putting the entire file into memory is not ideal, because the files can potentially be quite large.

+7
source share
4 answers

According to http://www.pkware.com/documents/casestudies/APPNOTE.TXT , a ZIP file begins with a "local file header signature"

0x50, 0x4b, 0x03, 0x04 

therefore, it is enough to read the first 4 bytes to check if the file is a ZIP file. A definite decision can only be made if you really try to extract the file.

There are many ways to read the first 4 bytes of a file. You can use NSFileHandle, NSInputStream, open / read / close, .... So this should be considered only as one of the possible examples:

 NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:@"/path/to/file"]; NSData *data = [fh readDataOfLength:4]; if ([data length] == 4) { const char *bytes = [data bytes]; if (bytes[0] == 'P' && bytes[1] == 'K' && bytes[2] == 3 && bytes[3] == 4) { // File starts with ZIP magic ... } } 

Swift 4 Version:

 if let fh = FileHandle(forReadingAtPath: "/path/to/file") { let data = fh.readData(ofLength: 4) if data.starts(with: [0x50, 0x4b, 0x03, 0x04]) { // File starts with ZIP magic ... } fh.closeFile() } 
+10
source

try it

 NSWorkspace *ws = [NSWorkspace sharedWorkspace]; NSString *description = [ws localizedDescriptionForType:[ws typeOfFile:@"/full/path/to/file" error:nil]]; 

Or for mime this

 + (NSString*) mimeTypeForFileAtPath: (NSString *) path { if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { return nil; } CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[path pathExtension], NULL); CFStringRef mimeType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType); CFRelease(UTI); if (!mimeType) { return @"application/octet-stream"; } return [NSMakeCollectable((NSString *)mimeType) autorelease]; } 
0
source

I would just use a file , then grep if it has the text "zip" or "Zip Archive" to be safe.

 if file -q $FILENAME | grep "Zip archive"; then echo "zip"; else echo "not zip"; fi 
0
source

Since both .zip and .xlsx have the same magic number, I could not find a valid zip file (if it was renamed).

So, I used Apache Tika to find the exact type of document.

Even if you rename the file type to zip, it finds the exact type.

Link to Apache tika use cases

0
source

Source: https://habr.com/ru/post/1496653/


All Articles