I need to determine if a file in my app's documents directory is a zip file. The file name cannot be used in making this determination. So I will need to be able read the MIME type or find some other property that only applies to zips.
NOTE: A solution that requires putting the entire file into memory is not ideal as files could potentially be pretty large.
so it is sufficient to read the first 4 bytes to check if the file is possibly a ZIP file. A definite decision can only be made if you actually try to extract the file. There are many methods to read the first 4 bytes of a file. You can use NSFileHandle, NSInputStream, open/read/close, ... .
ZIP files work in much the same way as a standard folder on your computer. They contain data and files together in one place. But with zipped files, the contents are compressed, which reduces the amount of data used by your computer. Another way to describe ZIP files is as an archive.
ZIP is an archive file format that supports lossless data compression. A ZIP file may contain one or more files or directories that may have been compressed. The ZIP file format permits a number of compression algorithms, though DEFLATE is the most common.
According to http://www.pkware.com/documents/casestudies/APPNOTE.TXT, a ZIP file starts with the "local file header signature"
0x50, 0x4b, 0x03, 0x04
so it is sufficient to read the first 4 bytes to check if the file is possibly a ZIP file. A definite decision can only be made if you actually try to extract the file.
There are many methods to read the first 4 bytes of a file. You can use NSFileHandle, NSInputStream, open/read/close, ... . So this should only be taken as one possible example:
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()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With