Creating a zip file with ionic.zip - c#

I have the following code set up to create a zip file of a set of doucments:
public bool CreateDocumentationZipFile(int documentIdentifier, string zipDestinationPath, IList<string> documentPaths)
{
bool zipped = false;
if (documentPaths.Count > 0)
{
using (ZipFile loanZip = new ZipFile())
{
loanZip.AddFiles(documentPaths, false, zipDestinationPath);
loanZip.Save(string.Format("{0}{1}.zip",zipDestinationPath, documentIdentifier.ToString()));
zipped = true;
}
}
return zipped;
}
The issue I have is that when the zip file is created, the folder structure is maintaned within the zip file:
e.g
I am creating a zip of a selection of documents located at
C:\SoftwareDevelopment\Branches\ScannedDocuments\
When the created zip file is opened, there is a folder structure within the zip as follows:
Folder 1 ("SoftwareDevelopment")
Inside Folder 1 is folder 2 ("Branches")
Inside Folder 2 is folder 3 ("ScannedDocuments")
the scanned documents folder then contains the actual scan files.
Can anyone tell me how I can just have the scan files in the zip without the folders path being maintained?

The documentation states that the third parameter
directoryPathInArchive (String)
Specifies a directory path to use to override any path in the file
name. 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 null (Nothing in
VB) will use the path on each of the fileNames, if any. Passing the
empty string ("") will insert the item at the root path within the
archive.
So if you always want to have the files added to the root of your zip archive, change
loanZip.AddFiles(documentPaths, false, zipDestinationPath);
to
loanZip.AddFiles(documentPaths, false, "");

Related

Package a Folder in C#

I'm looking to make a program to make my life easier, I need to be able to easily select a folder, which I can do, I don't need help with that. I want to take the directory of a folder, and put that folder into a new folder with a specified name, and then zip up that folder into a zip format in which I can change the name and filetype of. Is this possible in vanilla C#? I've only ever done files for text and I've never looked at moving and packaging files. SO I'm really clueless, I'd just like to be guided into the right direction.
Edit: I found this code online, but I need to put the folder inside another folder, may I adapt upon this to do so?
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
string extractPath = #"c:\example\extract";
ZipFile.CreateFromDirectory(startPath, zipPath);
ZipFile.ExtractToDirectory(zipPath, extractPath);
So, after an extended chat discussion, here's what we've established.
The goal is to put the contents of a source directory into a zip with the following structure:
- Payload
|- name of source
|-- contents of source
Okay, so, starting from an input path called startPath:
var parent = Path.GetDirectoryName(startPath);
var payload = Path.Combine(parent, "payload");
Directory.CreateDirectory(payload); // ensure payload ex
Directory.Move(startPath, Path.Combine(payload, Path.GetFileName(startPath));
var zipPath = Path.Combine(parent, "export.zip");
File.Delete(zipPath);
ZipFile.CreateFromDirectory(payload , zipPath, CompressionLevel.Optimal, true);
The key is that true in the CreateFromDirectory call, that puts the entries in the archive under a directory with the same name as the directory being zipped (in this case, "payload"). Feel free to change CompressionLevel to other values if you want.
Now, this has the side effect of actually physically moving the source directory, which might not be the best user experience. If you want to avoid that, you'll have to basically do what ZipFile.CreateFromDirectory does by hand, which is to enumerate the source directory yourself and then copy the files into the zip archive (in which case you can name those files whatever you want):
var parent = Path.GetDirectoryName(startPath);
var zipPath = Path.Combine(parent, "export.zip");
File.Delete(zipPath);
using var zip = ZipFile.Open(zipPath, ZipArchiveMode.Create);
foreach(var file in Directory.EnumerateFiles(startPath, "*", SearchOption.AllDirectories))
{
// get the path of the file relative to the parent directory
// this gives us a path that starts with the source directory name
// e.g. C:\example\start\file.txt -> start\file.txt
var relativePath = Path.GetRelativePath(parent, file);
// construct the path of the entry in the archive
// this is "Payload", and then the relative path of the file
// we need to fix up the separators because zip entries use /
// e.g. start\file.txt -> Payload/start/file.txt
var entryPath = Path.Combine("Payload", relativePath).Replace(Path.DirectorySeparatorChar, '/');
// put the file in the archive
// to specify a compression level, pass it as the third parameter here
zip.CreateEntryFromFile(file, entryPath);
}

Determine file or directory from string

I'm trying to extract some files from a Zip file, but the FastZip.ExtractZip method I was using is having some issues, for example:
Output location: C:\testing\output\
File 1: PhysicalMemory/idx - this is a file, but is created as a directory
File 2: c:/pagefile.sys/00000052 - This is a directory, but is created as a file
File 3: c:/pagefile.sys/00000052/index - This is a file, but is created as a directory
I'm not sure how to correctly identify these as files or directories, as some of the files don't have file extensions, which the FastZip package seems to use to identify files.
The ZipEntry class has a isDirectory method, but it's returning false for every entry, so I can't use that.
Does anyone have any suggestions on how to approach this?
Write your own is directory method to establish file or directory
public bool isDirectory(string path)
{
FileAttributes attr = File.GetAttributes(path);
if (attr.HasFlag(FileAttributes.Directory))
return true;
else
return false;
}

Usage of DotNetZip

I am using DotNetZip library to compress files. my code is given below
String[] filenames = { "D:\\Data\\ReadMe.txt", "c:\\data\\collection.csv","c:\\ProgramFiles\\reports AnnualSummary.pdf"};
using (ZipFile zip = new ZipFile())
{
zip.AddFiles(filenames, "files");
zip.Save("Archive.zip");
}
Now when the Archive.zip is created, there are folders created in the archive with the same name(e.g Data, ProgramFiles etc)for files in which they were stored.
My target is to compress all the files in Archive.zip without any folder in the archive. how can I achieve it?
The AddFiles has an overload to flatten the directory structure in the zip archive
public void AddFiles(
IEnumerable<string> fileNames,
bool preserveDirHierarchy,
string directoryPathInArchive
)
http://dotnetzip.herobo.com/DNZHelp/html/c64e89d3-2f1f-2886-16bc-291746b46718.htm
zip.AddFiles(filenames, false, "files");
The second parameter preserveDirHierarchy can be passed as false to have all files in the root of the zip archive. Be careful that you do not have files with the same name when doing this. It will throw an Exception for duplicate file names.

Creating zip file from multiple files

The code below is working fine in creating a zip file but the file created is having a folder IIS Deploy >>>WebService... then the text file and not just the text file.
How can I just add the text files to the zip file?
ZipFile z = ZipFile.Create("C:\\IIS Deploy\\WebServiceTest\\WebServiceTest\\Accident.zip");
//initialize the file so that it can accept updates
z.BeginUpdate();
//add the file to the zip file
z.Add("C:\\IIS Deploy\\WebServiceTest\\WebServiceTest\\test1.txt");
z.Add("C:\\IIS Deploy\\WebServiceTest\\WebServiceTest\\test2.txt");
z.Add("C:\\IIS Deploy\\WebServiceTest\\WebServiceTest\\test3.txt");
//commit the update once we are done
z.CommitUpdate();
//close the file
z.Close();
If you have everything within same folder then the easiest option is to use CreateFromDirectory class.
static void Main()
{
// Create a ZIP file from the directory "source".
// ... The "source" folder is in the same directory as this program.
// ... Use optimal compression.
ZipFile.CreateFromDirectory("source", "destination.zip",
CompressionLevel.Optimal, false);
// Extract the directory we just created.
// ... Store the results in a new folder called "destination".
// ... The new folder must not exist.
ZipFile.ExtractToDirectory("destination.zip", "destination");
}
http://www.dotnetperls.com/zipfile
Please note that it is applicable to .NET Framework 4.6 and 4.5

SharpZipLib - adding folders/directories to a zip archive

From examples, I've got a pretty good grasp over how to extract a zip file.
In nearly every example, the method of identifying when a ZipEntry is a directory is as follows
string directoryName = Path.GetDirectoryName(theEntry.Name);
string fileName = Path.GetFileName(theEntry.Name);
if (directoryName.Length > 0)
Directory.CreateDirectory(Path.Combine(destinationDirectory, directoryName));
if (fileName != String.Empty)
{
//read data and write to file
}
Now is is fine and all (directory encountered, create it), directory is available when the file is extracted.
I can add files to a zip fine, but how do I add folders? I understand I'll be looping through the directories, adding the files encountered (and their ZipEntry.Name property is populated properly), but how do I add a ZipEntry to the archive and instruct the ZipOutputStream that it is a directory?
ZipFile.AddDirectory does what you want. Small sample code here.

Categories