internal static ZipEntry AddOrUpdateDirectoryImpl(this ZipFile zipFile, string directoryName, string rootDirectoryPathInArchive, AddOrUpdateAction action, bool recurse, int level) { string fullPath = GetFullPath(directoryName); if (zipFile.StatusMessageTextWriter != null) zipFile.StatusMessageTextWriter.WriteLine("{0} {1}...", (action == AddOrUpdateAction.AddOnly) ? "adding" : "Adding or updating", directoryName); if (level == 0) { zipFile.SetAddOperationCanceled(false); zipFile.OnAddStarted(); } // workitem 13371 if (zipFile.IsAddOperationCanceled()) return null; string dirForEntries = rootDirectoryPathInArchive; ZipEntry baseDir = null; if (level > 0) { int f = directoryName.Length; for (int i = level; i > 0; i--) f = directoryName.LastIndexOfAny("/\\".ToCharArray(), f - 1, f - 1); dirForEntries = directoryName.Substring(f + 1); dirForEntries = Path.Combine(rootDirectoryPathInArchive, dirForEntries); } // if not top level, or if the root is non-empty, then explicitly add the directory if (level > 0 || rootDirectoryPathInArchive != "") { // add the directory only if it does not exist. // It's not an error if it already exists. dirForEntries = ZipEntryInternal.NameInArchive(dirForEntries) + '/'; if (!zipFile.EntryFileNames.Contains(dirForEntries)) { baseDir = zipFile.AddDirectoryByName(dirForEntries); } } if (!zipFile.IsAddOperationCanceled()) { IFile fileCheck = FileSystem.Current.GetFileFromPathAsync(fullPath).ExecuteSync(); if (fileCheck != null) { throw new IOException(string.Format("That path ({0}) is a file, not a directory!", directoryName)); } IFolder folder = FileSystem.Current.GetFolderFromPathAsync(fullPath).ExecuteSync(); if (folder == null) { throw new FileNotFoundException(string.Format("That folder ({0}) does not exist!", directoryName)); } IList<IFile> files = folder.GetFilesAsync().ExecuteSync(); if (recurse) { // add the files: foreach (IFile file in files) { if (zipFile.IsAddOperationCanceled()) break; if (action == AddOrUpdateAction.AddOnly) zipFile.AddFile(file.Path, dirForEntries); else zipFile.UpdateFile(file.Path, dirForEntries); } if (!zipFile.IsAddOperationCanceled()) { // add the subdirectories: IList<IFolder> dirs = folder.GetFoldersAsync().ExecuteSync(); foreach (IFolder dir in dirs) { zipFile.AddOrUpdateDirectoryImpl(dir.Path, rootDirectoryPathInArchive, action, recurse, level + 1); } } } } if (level == 0) zipFile.OnAddCompleted(); return baseDir; }
/// <summary> /// Add or update a directory in the zip archive at the specified root /// directory in the archive. /// </summary> /// /// <remarks> /// If the specified directory does not exist in the archive, then this method /// is equivalent to calling <c>AddDirectory()</c>. If the specified /// directory already exists in the archive, then this method updates any /// existing entries, and adds any new entries. Any entries that are in the /// zip archive but not in the specified directory, are left alone. In other /// words, the contents of the zip file will be a union of the previous /// contents and the new files. /// </remarks> /// /// <seealso cref="Ionic.Zip.ZipFile.UpdateFile(string,string)"/> /// <seealso cref="Ionic.Zip.ZipFile.AddDirectory(string,string)"/> /// <seealso cref="Ionic.Zip.ZipFile.UpdateItem(string,string)"/> /// /// <param name="directoryName"> /// The path to the directory to be added to the zip archive, or updated /// in the zip archive. /// </param> /// /// <param name="directoryPathInArchive"> /// Specifies a directory path to use to override any path in the /// <c>directoryName</c>. This path may, or may not, correspond to a real /// directory in the current filesystem. If the files within the zip are /// later extracted, this is the path used for the extracted file. Passing /// <c>null</c> (<c>Nothing</c> in VB) will use the path on the /// <c>directoryName</c>, if any. Passing the empty string ("") will insert /// the item at the root path within the archive. /// </param> /// /// <returns> /// The <c>ZipEntry</c> corresponding to the Directory that was added or updated. /// </returns> public static ZipEntry UpdateDirectory(this ZipFile zipFile, string directoryName, String directoryPathInArchive) { return zipFile.AddOrUpdateDirectoryImpl(directoryName, directoryPathInArchive, AddOrUpdateAction.AddOrUpdate); }
internal static ZipEntry AddOrUpdateDirectoryImpl(this ZipFile zipFile, string directoryName, string rootDirectoryPathInArchive, AddOrUpdateAction action) { if (rootDirectoryPathInArchive == null) { rootDirectoryPathInArchive = ""; } return zipFile.AddOrUpdateDirectoryImpl(directoryName, rootDirectoryPathInArchive, action, true, 0); }