I'm attempting to create a zip file to serve as a backup of a directory, and eventually save that backup inside a "backups" folder in that directory. For illustration, "folder" includes "subFolder", "file1.txt", "file2.txt", and "backups". The "backups" folder would contain various earlier backup files. I want to create an archive of "folder" and all its contents, including subfolder, but exclude "backups".
Here is what I originally wanted to use:
ZipFile.CreateFromDirectory(folderToZip, backupFileName);
I realize there are problems with saving a zip file inside the folder being zipped, so I intended to save it somewhere else and then transfer it. But I don't know how to easily create an archive without the backups folder. My only thought is to write my own method recursively traversing the directory and excluding that one folder. It seems like there must be a simpler way.
Any help would be greatly appreciated!
Creating a zip folder allows files to be organized and compressed to a smaller file size for distribution or saving space. Zip folder can have subfolders within this main folder.
Syntax : $zip –m filename.zip file.txt 4. -r Option: To zip a directory recursively, use the -r option with the zip command and it will recursively zips the files in a directory. This option helps you to zip all the files present in the specified directory.
To place multiple files into a zip folder, select all of the files while hitting the Ctrl button. Then, right-click on one of the files, move your cursor over the “Send to” option and select “Compressed (zipped) folder”.
To zip (compress) a file or folder Locate the file or folder that you want to zip. Press and hold (or right-click) the file or folder, select (or point to) Send to, and then select Compressed (zipped) folder. A new zipped folder with the same name is created in the same location.
Unfortunately, ZipFile
does not offer a method that lets you filter entries. Fortunately, you can easily create a method like this based on this implementation:
public static class ZipHelper {
public static void CreateFromDirectory(
string sourceDirectoryName
, string destinationArchiveFileName
, CompressionLevel compressionLevel
, bool includeBaseDirectory
, Encoding entryNameEncoding
, Predicate<string> filter // Add this parameter
) {
if (string.IsNullOrEmpty(sourceDirectoryName)) {
throw new ArgumentNullException("sourceDirectoryName");
}
if (string.IsNullOrEmpty(destinationArchiveFileName)) {
throw new ArgumentNullException("destinationArchiveFileName");
}
var filesToAdd = Directory.GetFiles(sourceDirectoryName, "*", SearchOption.AllDirectories);
var entryNames = GetEntryNames(filesToAdd, sourceDirectoryName, includeBaseDirectory);
using(var zipFileStream = new FileStream(destinationArchiveFileName, FileMode.Create)) {
using (var archive = new ZipArchive(zipFileStream, ZipArchiveMode.Create)) {
for (int i = 0; i < filesToAdd.Length; i++) {
// Add the following condition to do filtering:
if (!filter(filesToAdd[i])) {
continue;
}
archive.CreateEntryFromFile(filesToAdd[i], entryNames[i], compressionLevel);
}
}
}
}
}
This implementation lets you pass a filter that rejects all entries from the "backup/"
directory:
ZipHelper.CreateFromDirectory(
myDir, destFile, CompressionLevel.Fastest, true, Encoding.UTF8,
fileName => !fileName.Contains(@"\backup\")
);
In my opinion, you can take every file inside the folder excluding the "backups" folder and make an temporary folder with them to make the zip as you have said.
With this LINQ query you can do it in a really simple way:
List<FileInfo> files = di.GetFiles("*", SearchOption.AllDirectories).Where(file => !file.DirectoryName.Contains("backups")).ToList();
Once you have this list, you can copy all this files, make the zip and erase the content. I can not see a simpler way.
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