Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine if a file is a zip file?

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.

like image 506
user1023127 Avatar asked Aug 12 '13 19:08

user1023127


People also ask

How do you check if the file is ZIP file or not?

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, ... .

What is the difference between a file and a ZIP file?

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.

What kind of file format is a ZIP file?

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.


1 Answers

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()
}
like image 145
Martin R Avatar answered Oct 07 '22 20:10

Martin R