c# extract zip file with directory - c#

I'm using c# fw4.5.
I have a simple code extracting a zip file.
foreach(ZipArchiveEntry entry in z.entries) //z is a zip file open in ZipArchiveMode.Read
{
entry.ExtractToFile(entry.FullName);
}
The zip file have a directory inside it and all files are inside that directory.
When I look at the z.Entries I see its an array which place [0] is only the directory and [1],[2],[3] are files.
But when its try to do:
entry.ExtractToFile(entry.FullName);
On the first entry, I get an error:
"The filename, directory name or volume label syntax is incorrect".
I can't seems to find out whats wrong. Do I need to anything also for it to open the directory? Maybe because the entry is a directory only the "ExtractToFile(entry.FullName)" can't work?
Thanks in advanced.

According to this MSDN article, the ExtractToFile method expects a path to a file (with an extension) and will throw an ArgumentException if a directory is specified.
Since the first entry in the archive is a directory and you are using its name as the argument, that is why you are having this issue.
Look into the related ExtractToDirectory method, which is used like so:
ZipFile.ExtractToDirectory(#"c:\zip\archive.zip", #"c:\extract\");

In addition to Tonkleton's answer I would suggest that you use a third-party compression library since ZipArchive is not supported for framework versions before the .Net 4.5 framework, might I suggest DotNetZip as mentioned in other questions regarding compression in earlier frameworks on StackOverflow.

Replace your paths:
void Main()
{
var zipPath = #"\\ai-vmdc1\RedirectedFolders\jlambert\Downloads\cscie33chap1and2.zip";
var extractPath = #"c:\Temp\extract";
using (ZipArchive z = ZipFile.OpenRead(zipPath))
{
foreach(ZipArchiveEntry entry in z.Entries) //z is a zip file open in ZipArchiveMode.Read
{
entry.ExtractToFile(Path.Combine(extractPath, entry.FullName), true);
}
}
}

Related

Could not find a part of the path while using File.Copy c# .net 4.7.2

I'm using the following code just to copy a file from a smaller filepath into a longer file path (> 260 characters).
string dbCDataPath = Path.Combine(DYRECTORY_WITH_GUARANTEE_ACCESS,Path.GetFileName(pathFileName));
string targetFile = Path.Combine(Path.GetDirectoryName(pathFileName), Path.GetFileName(pathFileName));
File.Copy(dbCDataPath, targetFile, true);
I'm getting Could not find a part of the path error and I don't know why I have double checked both the source and the destination folders, both exists.
Any help will be highly appreciated.
You need to call File.Copy like this:
File.Copy(targetFile, dbCDataPath, true);
The first parameter of this method is sourceFile you want to copy, the second parameter is destination path.

Read content zip on dropbox with c#

I'm trying to read some images that are in a zip in dropbox. So I need to access to this file and get the images, but I don't know what i'm doing wrong. I'm doing like this:
string uri_zip = new Uri(string.Format("My Path of the zip in Dropbox")).AbsoluteUri;
using (ZipArchive zip = ZipFile.Open(uri_zip, ZipArchiveMode.Read))
{
foreach (ZipArchiveEntry entry in zip.Entries)
{
images.Add(entry.Name.Substring(0, entry.Name.LastIndexOf(#".")));
}
}
Any solution?
If you look at ZipFile.Open it says that the first string argument is "The path to the archive to open, specified as a relative or absolute path."
I believe that it doesn't work with the remote, most probably HTTPS URI i.e. it probably won't work with that dropbox URI that you are trying to pass as an argument to the Open() function.
Try to download the file first using HttpClient and then use it from the local file system, or see if the Dropbox API supports working with an archive on the server-side.

Opening Split Zip Files With DotNetZip

I am trying to extract files from zip files using the DotNetZip library. I am able to extract files when it is a single .zip file. However, when I try to extract files from a multi volume zip file like Something.zip.0 or Something.zip.1, I get the following two exceptions:
-Exception thrown: 'Ionic.Zip.BadReadException' in Ionic.Zip.dll
-Exception thrown: 'Ionic.Zip.ZipException' in Ionic.Zip.dll
Is it possible for DotNetZip to read these type of files, or should I be looking into an alternative approach? I am working on Visual Studios using C#.
Here's a snippet of how I implement my zip file extraction.
using (Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(_pathToZip))
{
zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestSpeed;
foreach(Ionic.Zip.ZipEntry ze in zip)
{
string fileName = ze.FileName;
bool isThereItemToExtract = isThereMatch(fileName.ToLower(), _folderList, _fileList);
if (isThereItemToExtract)
{
string pathOfFileToExtract = (_destinationPath + "\\" + ze.FileName).Replace('/', '\\');
string pathInNewZipFile = goUpOneDirectoryRelative(ze.FileName);
ze.Extract(_destinationPath, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently);
_newZip.AddItem(pathOfFileToExtract, pathInNewZipFile);
}
}
_newZip.Save();
}
Please refer the DotNetZipLibrary code examples:
using Ionic.Zip;
private void MyExtract(string zipToUnpack, string unpackDirectory)
{
using (ZipFile zip1 = ZipFile.Read(zipToUnpack))
{
// here, we extract every entry, but we could extract conditionally
// based on entry name, size, date, checkbox status, etc.
foreach (ZipEntry e in zip1)
{
e.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
}
}
This method should be able to extract either split and not split zip files.
Every zip entry will be extracted with its full path as specified in the zip archive, relative to the current unpackDirectory.
There's no need to check if zip entry exsists (isThereItemToExtract). Interating the zip entries with foreach should do the job.
To avoid collisions you need to check if file with same name as zipEntry exsists in the unpackDirectory, or use ExtractExistingFileAction.OverwriteSilently flag.
Is it possible for DotNetZip to read these type of files, or should I be looking into an alternative approach? I am working on Visual Studios using C#.
In my experience, this is the best library to deal with split zip files.

Using .NET ZipArchive to zip entire directories AS well as extra info

I inherited some code that makes use of ZipArchive to save some information from the database. It uses BinaryFormatter to do this. When you look at the zip file with 7-zip (for example), you see a couple of folders and a .txt file. All is working well. I simply want to modify the code to also have a folder in the ZipArchive called "temp" that consists of files and folders under C:\temp. Is there an easy way to add a entry (ZipArchiveEntry?) that consist of an entire folder or the disc? I saw "CreateEntryFromFile" in the member methods of ZipArchive, but no CreateEntryFromDirectory. Or perhaps there's some other simple way to do it? Anyone have example code? I should say that C:\temp could have variable number of files and directories (that have child directories and files, etc.) Must I enumerate them somehow, create my own directories use CreateEntryFromFile? Any help is appreciated.
Similarly, when I read the ZipArchive, I want to take the stuff related to C:\temp and just dump it in a directory (like C:\temp_old)
Thanks,
Dave
The answer by user1469065 in Zip folder in C# worked for me. user1469065 shows how to get all the files/directories in the directory (using some cool "yield" statements) and then do the serialization. For completeness, I did add the code to deserialize as user1469065 suggested (at least I think I did it the way he suggested).
private static void ReadTempFileStuff(ZipArchive archive) // adw
{
var sessionArchives = archive.Entries.Where(x => x.FullName.StartsWith(#"temp_directory_contents")).ToArray();
if (sessionArchives != null && sessionArchives.Length > 0)
{
foreach (ZipArchiveEntry entry in sessionArchives)
{
FileInfo info = new FileInfo(#"C:\" + entry.FullName);
if (!info.Directory.Exists)
{
Directory.CreateDirectory(info.DirectoryName);
}
entry.ExtractToFile(#"C:\" + entry.FullName,true);
}
}
}

Using SharpZipLib to update a zip - something bad if the entry name includes folder

This is my code to update an existing zip, the callers pass in the ZipFile and have a finally block to close the zipfile.
private static void AddFiles(ZipFile zipFile, string path, string filesEntryLocation, string pattern = #"*") {
zipFile.BeginUpdate();
string[] files = Directory.GetFiles(path, pattern);
foreach (string filename in files) {
zipFile.Add(filename, (filesEntryLocation + filename.Split(new[] { '\\' }).Last()).Replace('\\','/'));
}
zipFile.CommitUpdate();
}
As you can see I'm adding entries into the zip and setting the entryname to be in a specific part of the zip folder hierarchy.
We are doing this to inject a product into a 'framework' web package - the framework supports loosely coupled products.
The result zip is fine, I can navigate it in Windows, I can extract it...
BUT MSDeploy comes along and where ever a new entry resulted in an addition to zip folder hierarchy, I get errors from msdeploy saying it couldn't open the zip - BUT only at that specific i.e. the zip is not completely corrupt, it's only where msdeploy starts navigating done a 'new' folder.
Now, if I extract the changed zip, and then re-zip it (using 7zip), and ask msdeploy to execute against that - no problem it works.
SO - is this SharpZipLib, or am I doing something wrong in adding to the zip folder hierarchy?
You should also add the folder entries to archive (if they do not exist before).

Categories