The stream that is internally created by the CreateFromDirectory method remains opened and the user can't close it:
This is error message observed when using the below code snippet:
The process cannot access the file 'C:\Users\dyordano\OneDrive - Progress Software Corporation\MyProjects\1640071ZipFileCreateFromDirectory\myzip.zip' because it is being used by another process.
static void Main(string[] args)
string archiveFileName = @"..\..\myzip.zip";
string sourceDirectoryName = @"..\..\Folder";
File.Delete(archiveFileName);
Telerik.Windows.Zip.Extensions.ZipFile.CreateFromDirectory(sourceDirectoryName, archiveFileName, Telerik.Windows.Zip.CompressionLevel.Optimal, true);
using (Stream stream = File.Open(archiveFileName, FileMode.Open))
}
Workaround:
static void Main(string[] args)
string archiveFileName = @"..\..\myzip.zip";
string sourceDirectoryName = @"..\..\Folder";
File.Delete(archiveFileName);
CreateFromDirectory(sourceDirectoryName, archiveFileName, Telerik.Windows.Zip.CompressionLevel.Optimal, true);
using (Stream stream = File.Open(archiveFileName, FileMode.Open))
private static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName, Telerik.Windows.Zip.CompressionLevel compressionLevel, bool includeBaseDirectory)
Encoding entryNameEncoding = null;
DeflateSettings compressionSettings = new DeflateSettings()
CompressionLevel = compressionLevel,
HeaderType = CompressedStreamHeader.None
char[] directorySeparatorChar = new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
sourceDirectoryName = Path.GetFullPath(sourceDirectoryName);
destinationArchiveFileName = Path.GetFullPath(destinationArchiveFileName);
FileStream fileStream = File.Open(destinationArchiveFileName, FileMode.CreateNew, FileAccess.Write, FileShare.None); ;
using (ZipArchive zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Create,false, entryNameEncoding))
bool empty = true;
DirectoryInfo directoryInfo = new DirectoryInfo(sourceDirectoryName);
string fullName = directoryInfo.FullName;
if (includeBaseDirectory && directoryInfo.Parent != null)
fullName = directoryInfo.Parent.FullName;
foreach (FileSystemInfo fileSystemInfo in directoryInfo.EnumerateFileSystemInfos("*", SearchOption.AllDirectories))
empty = false;
int length = fileSystemInfo.FullName.Length - fullName.Length;
string entryName = fileSystemInfo.FullName.Substring(fullName.Length, length);
entryName = entryName.TrimStart(directorySeparatorChar);
DirectoryInfo subfolder = fileSystemInfo as DirectoryInfo;
if (subfolder != null)
if (IsDirectoryEmpty(subfolder))
zipArchive.CreateEntry(string.Concat(entryName, Path.DirectorySeparatorChar));
ZipFile.CreateEntryFromFile(zipArchive, fileSystemInfo.FullName, entryName, compressionSettings);
if (includeBaseDirectory && empty)
zipArchive.CreateEntry(string.Concat(directoryInfo.Name, Path.DirectorySeparatorChar));
private static bool IsDirectoryEmpty(DirectoryInfo directoryInfo)
bool empty = true;
using (IEnumerator<FileSystemInfo> enumerator = directoryInfo.EnumerateFileSystemInfos("*", SearchOption.AllDirectories).GetEnumerator())
if (enumerator.MoveNext())
empty = false;
return empty;
}
Note: We should ensure that all of the obsolete API that used to use the "leave open" flag don't keep the stream locked.
Hi Joe,
I checked the code snippet from this ticket thread and I can confirm there is an error message when extacting a zip archive that contains an empty folder I logged an item on your behalf in order to investigate this unexpected behavior:
ZipLibrary: 7zip reports errors while extracting archive containing empty folders
. Please, make sure to subscribe to the task so we can notify you when its status changes.
On the other hand, with the sample project I created the archive could be successfully exported (even with the error message). The output can be seen in the attached "
observed.gif
"
As for setting the last modified date, you can check the ZipArchive entry`s
LastWriteTime
property. An example can be found in "
Example 4: Set last entry's write time
" in the
ZipArchive Entry
help article.
Regards,
Martin
Progress Telerik
A brand new
ThemeBuilder
course was just added to the Virtual Classroom. The training course was designed to help you get started with
ThemeBuilder
for styling Telerik and Kendo UI components for your applications. You can check it out at
https://learn.telerik.com
Attached Files:
observed.gif
The workaround code seems to have an issue: While empty folders do get added to the ZIP file, these do not get extracted when unzipping (neither with 7-ZIP nor with the Windows built-in ZIP extension). I also noted that folders added by this method do not have a "last modified" date in the ZIP file.
What needs to be done that empty folders added to a ZIP file also get extracted as empty folders?
Hi,
I have added a temporary solution for handling the cases when opening an existing zip with the ZipFile.Open method for example:
static void Main(string[] args)
string path = @"path-to-file.zip";
using (ZipArchive zip = OpenAndClose(path, ZipArchiveMode.Read))
foreach (var entry in zip.Entries)
if (entry.Name == "TemplateSample.docx")
entry.ExtractToFile(@"unzipped-file-name.docx", true);
File.Delete(path);
public static ZipArchive OpenAndClose(string archiveFileName, ZipArchiveMode mode, Encoding entryNameEncoding=null)
FileMode fileMode;
FileAccess fileAccess;
FileShare fileShare;
ZipArchive zipArchive;
switch (mode)
case ZipArchiveMode.Read:
fileMode = FileMode.Open;
fileAccess = FileAccess.Read;
fileShare = FileShare.Read;
break;
case ZipArchiveMode.Create:
fileMode = FileMode.CreateNew;
fileAccess = FileAccess.Write;
fileShare = FileShare.None;
break;
case ZipArchiveMode.Update:
fileMode = FileMode.OpenOrCreate;
fileAccess = FileAccess.ReadWrite;
fileShare = FileShare.None;
break;
default:
throw new ArgumentOutOfRangeException("mode");
FileStream fileStream = null;
fileStream = File.Open(archiveFileName, fileMode, fileAccess, fileShare);
bool leaveOpen = false;
zipArchive = new ZipArchive(fileStream, mode, leaveOpen, entryNameEncoding);
catch
if (fileStream != null)
fileStream.Dispose();
throw;
return zipArchive;
}
Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik