How to zip all files in folder - c#

I have a folder "D:\folder" and in this folder I have 10 files that I need to zip into a new archive "D:\folder.zip".
Currently I'm using ICSharpCode.SharpZipLib but this is not a mandatory requirement, so other solutions are acceptable.
The problem I'm facing is that when I try to execute the method FileStream fs = File.OpenRead(#"D:\folder") I get an error because of access to the specifided path.
How can I zip these files in a simple way?

DotNetZip is much easier to use than SharpZipLib, example of zipping all files in folder :
using (ZipFile zip = new ZipFile())
{
zip.AddDirectory(#"MyDocuments\ProjectX", "ProjectX");
zip.Save(zipFileToCreate);
}
This is a an example from this page :
http://dotnetzip.codeplex.com/wikipage?title=CS-Examples&referringTitle=Examples

I also agree with the suggestion of Antonio Bakula to use DotNetZip instead of SharpZipLib.
.NET 4.5 includes the new ZipArchive and ZipFile classes for manipulating .zip files. With this support what you are trying to do is accomplished by:
ZipFile.CreateFromDirectory(#"D:\Folder", #"Folder.zip");
As a side note the reason you get the error is because you're trying to open a directory instead of a file. The File.OpenRead is used to open a file for read, since you provide a directory, you get the error. If you want to enumerate the files or directories inside a specific folder you can instead use Directory.EnumerateFiles or Directory.EnumerateDirectories.

Related

Add all folder items into archive using c#

I want to add(and overwrite) all files including other folders that are in single folder.
Example:
In archive zip.zip:
work.docx
1.txt
Photos
|_ocean.png
|_horse.png
After adding files & folder from another folder it would be like:
work.docx
1.txt
code.cs
Photos
|_ocean.png
|_horse.png
Program
|_program.exe
|_config.txt
I tried to do that with Ionic's zip library:
Ionic.Zip.ZipFile zf = Ionic.Zip.ZipFile.Read(#"C:\\zip.zip");
zf.UpdateDirectory(#"C:\\Program");
zf.Save();
It works, but it doesn't overwrite files.
If you are using .NET 4.5 then you can use
System.IO.Compression.ZipArchive
It allows a single step compression.
ZipFile.CreateFromDirectory(#”C:\zip”, #”C:\zip.zip”);
To update it you can use ZipArchiveMode.Update

Executing WinZip Command in a C# Program

How to execute winzip command from MVC controller Action?
Command:
C:\Program Files (x86)\WinZip>WZZIP.EXE -ys2048000 Location Location
What you are asking, directly is possible with the System.Diagnostics.Process.Start(string, string) method. It would look something like this:
System.Diagnostics.Process.Start(
#"C:\Program Files (x86)\WinZip\WZZIP.EXE",
"-ys2048000 Location Location");
I've gone down this path and for simple things it is probably good enough. I've often found that there are usually more cool, useful things you can do interacting directly with the zip files. In that case, something like DotNetZip or SharpZip are probably good alternatives. I've used DotNetZip before, its very robust and highly performant.
Here's a quick example from DotNetZip home page:
Here's some C# code that creates a zip file.
using (ZipFile zip = new ZipFile())
{
// add this map file into the "images" directory in the zip archive
zip.AddFile("c:\\images\\personal\\7440-N49th.png", "images");
// add the report into a different directory in the archive
zip.AddFile("c:\\Reports\\2008-Regional-Sales-Report.pdf", "files");
zip.AddFile("ReadMe.txt");
zip.Save("MyZipFile.zip");
}
I would add the following package and use that rather than trying to connect to an exe file (which you'll more than likely not have permission to do so):
https://www.nuget.org/packages/DotNetZip/

How to zip selected files? not all the files in a directory in c#

I want to zip some files in a directory. I have googled a lot but i always saw examples about zipping a directory (all files in directory) by the code below:
string startPath = #subPath;
string zipPath = #"C:\result.zip";
ZipFile.CreateFromDirectory(startPath, zipPath);
I am referencing System.IO.Compression.Filesystem.dll
This code zips all the files in the directory referenced by startPath.
I tried ZipArchive class for compressing but it compress file with directories on its path. For example,
assume i want to zip "a.txt" located at "C:\directories\Graphics\a.txt". The zip file contains directories "directories" and "Graphics" and into these directories the file "a.txt". It is not a good solution to cut files then erase the directories and paste again since i am working on big size data.
How can I zip only some of files at a directory?
How can I zip some files that are located in different directories?
I am looking up the subject for 2 days. Is it a kind of constraint in .Net?
You can use the ZipArchive class, first create it and then - once created you just add ZipArchiveEntry objects into the archive. Each of the ZipArchiveEntry objects represents a single file that you will add to the archive.
Some tips:
You can find more info and a sample of how this could be done on MSDN, here: http://msdn.microsoft.com/pl-pl/library/system.io.compression.ziparchive(v=vs.110).aspx and here: http://msdn.microsoft.com/pl-pl/library/system.io.compression.ziparchiveentry(v=vs.110).aspx.
This may not be an exact solution but should work for your scenario. I'll give you the steps :
Create a Temporary Directory
Read and copy your Selected files into the Temporary directory. This applies to your second scenario as well.
Zip the temporary directory
Delete Temporary Directory after you are done
I would recommend using File.Copy to copy all your desired files to a temporary directory, then zip them all from there and delete the temporary directory once the zip operation has finished.

Saving multiple files types into one file

I'm developing a 3D application in which the user may load multiple images, the 3D library I use has a function to export the whole scene as XAML, of course in XAML I only have the path to the images, so the file will only be valid on the machine in which it has been created, what I want to do is to save the XAML , change image(s) path inside the XAML to be relative to the XAML file path, save image(s) along the XAML in the same new file, like this the new file will always contain the XAML and the images. how to save multiple files types within the same file ? any other suggestions on the whole idea would be appreciated.
If you are using .NET 4.5, then you can programmatically save multiple files into a zip folder easily using the new ZipFile class.
First, you'll need to prepare your files into a new folder (Directory.CreateDirectory, File.Move) and then you can simply use the ZipFile.CreateFromDirectory Method (adapted from the linked page):
string filePathOfNewFolder = #"c:\example\start";
string zipFilePath = #"c:\example\result.zip";
ZipFile.CreateFromDirectory(filePathOfNewFolder, zipFilePath);
UPDATE >>>
For .NET 4, you might have to rely more on third party libraries. You can download the DotNetZip library from the DotNetZip - Zip and Unzip in C#, VB, any .NET language page on CodePlex. It also works fairly simply. Here is an example taken from the linked page:
using (ZipFile zip = new ZipFile())
{
// add this map file into the "images" directory in the zip archive
zip.AddFile("c:\\images\\personal\\7440-N49th.png", "images");
// add the report into a different directory in the archive
zip.AddFile("c:\\Reports\\2008-Regional-Sales-Report.pdf", "files");
zip.AddFile("ReadMe.txt");
zip.Save("MyZipFile.zip");
}
Store your XAML and other image files into one file (e.g. zip or cab).
When running your program, unzip relevant file into a temp folder so you can get the relevant path working.
Empty the temp folder afterwards if required.

System.IO.Packaging library does not read standard windows zip files

When reading a zip package using the System.IO.Packaging assembly, I have found that zip files created using the standard windows zip utility are unable to be read (the package parts (internal files) of the zip package show as not existing).
After doing some research it appears that this is because the System.IO.Packaging library adds a Content_Types.xml to the zip when it is created, which does not appear to be present in a standard windows compressed zip.
Example:
using (Package Zip = Package.Open(BundlePath, FileMode.Open))
{
Uri FileUri = PackUriHelper.CreatePartUri(new Uri("somefile.xml", UriKind.Relative));
if (!Zip.PartExists (FileUri )) //this fails even though the file exists in the zip
throw new ResourceException(String.Format("Zip {0} does not contain file", BundlePath));
...
Is there anyway to still use the packaging system provided by .NET to read standard zip files, or do they need to be created using the library.
Edit:
Adding this file (Content_Types.xml) manually, and zipping using the Windows compression utility, proves to be successful in allowing the package to read.
Thanks.
System.IO.Packaging isn't there to read zip files but packages. Use DotnetZip instead.
Unfortunately I believe you are correct there isn't a good way to get the System.IO.Packaging libraries to open up any file in a standard zip format that doesn't contain that [content_types].xml file.
I was working on this issue a few months back, and this is what I was trying to implement something that would inject this file before we just decided to initially generate all of our files from within .NET:
the format of the zip file is the following
(---file 1---)(---file 2---)...(---file x---)(table of contents)
Without a third party library you should be able to open up a zip file as a binary file, hop to the end and read that table of contents, add a [content_types].xml file at the end with the types/default extension info, adjust the table of contents entries, append it to the end of the file, and go. The problem I was running into when trying to implement this is there are various checksums on the file to verify that it hasn't been corrupted, I hadn't gotten them all by the time I needed to change directions on this.
I'm sure this is more info that you needed, but should you decide to implement your own solution hopefully this helps.

Categories