User (Old forums)MemberJanuary 31, 2005 at 6:07 pmPost count: 23064
What is the best way to detect a file is a Zip file or a self extracting zip file ? (besides the extension)?
Imported from legacy forums. Posted by Alin (had 4452 views)User (Old forums)MemberFebruary 2, 2005 at 9:12 amPost count: 23064
If the file is non-empty, try creating a ZipArchive for it. It will throw if an ending header cannot be found. Something like this:
<code>bool isZipFile = false;
DiskFile file = new DiskFile( myFilename );
if( file.Exists && file.Size > 0 )
ZipArchive zip = new ZipArchive( file );
isZipFile = true;
// isZipFile is true if an ending header and central directory could be read. It’s a zip file.
Imported from legacy forums. Posted by Martin (had 190 views)User (Old forums)MemberFebruary 2, 2005 at 9:21 amPost count: 23064
I was thinking about a more clean method, throwing exceptions is an expensive operation, considering that I have to check maybe more than one file a second. Only like 10% may be actual zip files, so throwing exceptions will really slow down my application. For detecting .zip files, although not a good practice, I can use the magic number. Is there a magic number for zip sfx ? or another method I can use so I don’t have to use the exceptions ?
Imported from legacy forums. Posted by Alin (had 203 views)User (Old forums)MemberFebruary 2, 2005 at 10:00 amPost count: 23064
There is no built-in solution to detect zip files, but I’ll add this to the feature request list.
In the meantime, there are two ways you could implement such a method.
The first one involves finding the beginning of the zip file. A non-empty zip file always starts with bytes 0x50, 0x4b, 0x03, 0x04. This signature may not be at the very beginning, as it could be preceeded by the binary code if it’s an EXE, or by a spanning signature (0x50, 0x4b, 0x07, 0x08) if the zip file spans multiple disks, or is split in pieces. You could try locating this signature in the first 150kb.
The second one involves finding the ending header. It starts with signature 0x50, 0x4b, 0x05, 0x06, and is always located within the last 64kb of the zip file (the last part in case it spans or splits). I prefer this one since an empty zip file could have no local header, but still have an ending header, and the size of the data preceeding the first local header can be infinite, as opposed to any trailing data after the ending header which is limited to 64kb minus ending header size per the zip file format. Thus, you’re always sure to find that ending header in the last 64kb if it’s a zip file. If you want a more rigourus verification, you can verify if the data following the signature matches a valid ending header. It looks like this:
I. End of central directory record:
end of central dir signature 4 bytes (0x06054b50)
number of this disk 2 bytes
number of the disk with the
start of the central directory 2 bytes
total number of entries in the
central directory on this disk 2 bytes
total number of entries in
the central directory 2 bytes
size of the central directory 4 bytes
offset of start of central
directory with respect to
the starting disk number 4 bytes
.ZIP file comment length 2 bytes
.ZIP file comment (variable size)
If the “total number fo entries in the central directory” is greater than zero, you could check at the “offset of start of central directory” if you find the 0x50, 0x4b, 0x01, 0x02 signature (central header signature).
Hope this helps. I’ll take note of the possibility of adding a “static bool IsZipFile()” method to ZipArchive. Could be cool.
Imported from legacy forums. Posted by Martin (had 1187 views)User (Old forums)MemberFebruary 2, 2005 at 3:23 pmPost count: 23064
Thanks a lot. It will be nice to have this feature in a future version of xCeed Zip .NET. Meanwhile I’ll use the second method with the ending header.
Imported from legacy forums. Posted by Alin (had 201 views)
- You must be logged in to reply to this topic.