I am handling some 3rd party ZIP files with .Net 4.5.2 System.IO.Compression.ZipArchive class and all works nicely.
However, I need to tell apart file entries from directory entries, preferably without extracting them first.
Is there a way to tell if a ZipArchive entry is a directory without extracting it?
As far as could find out there is no property of ZipArchiveEntry that tells if it is a file or directory.
Seems like I really do tend to answer my own questions.
Anyway, the answer is straight forward:
If ZipArchiveEntry
is a directory it will have its FullName
property ending with "/" (e.g. "some_dir/") and its Name
property will be empty string ("").
If only someone cared to put that info in the documentation ...
Oh, and there is a catch:
If a directory contains files, there does not have to be a separate ZipArchiveEntry
for it.
So, if you are looking for a specific directory you cannot just look for one ZipArchiveEntry
with empty Name
or with "/" at the end of FullName
- you have to parse the whole tree (FullName
for each ZipArchiveEntry
).
Luckily I had only to check if there is a single common directory for all entries (FullName
properties of all ZipArchiveEntry
items shoud start with the same string in the form of "folder_name/").
ICSharpZipLib does it like this:
public bool IsDirectory
{
get
{
int nameLength = name.Length;
bool result =
((nameLength > 0) &&
((name[nameLength - 1] == '/') || (name[nameLength - 1] == '\\'))) ||
HasDosAttributes(16)
;
return result;
}
}
public bool IsFile
{
get
{
return !IsDirectory && !HasDosAttributes(8);
}
}
one could write these as extension methods for ZipArchiveEntry
Old question but I think it has a better solution than the one provided here. ZipArchiveEntry has a property named ExternalAttributes. Looks like this has been available since .Net Framework 4.7.2
According to MS docs "...low order byte is the MS-DOS directory attribute byte...".
Therefore all you need to do is to take the low byte, cast it as FileAttributes and check the attributes if it is a "Directory" or not.
var lowerByte = (byte)(atributeValue & 0x00FF);
var attributes = (FileAttributes)lowerByte;
Now just check the attributes to see if it is a directory (folder)
if (attributes.HasFlag(FileAttributes.Directory)) {...}
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