DotNetZip Extract Folder & Contents based on folder comment - c#

I have some code that adds different directories to a zip file. Its important that I know each folder based on its comment, during the extraction process. Here is the zip sample code:
foreach (string folder in BackupDIRS)
{
string Source = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), folder);
string Folder = Path.GetFileName(Path.GetDirectoryName(Source));
ZipEntry e = zip.AddDirectory(Source, Folder);
e.Comment = "comment here";
}
Here is the code for unzipping:
using (ZipFile zip1 = ZipFile.Read(src))
{
foreach (ZipEntry e in zip1.Entries)
{
// e.comment will be null on actual files.
}
}
The actual entry points for the folder have comments but their files dont, which presents a problem since it will cause most entries to have null comments.
How do I make the files have the same comment as the folder, or does DotNetZip extract directory files sequentially, meaning if its null I could use the last non null value because it would be that folder's files.

After calling ZipEntry e = zip.AddDirectory(Source, Folder); you can iterate through all files in ZipEntry and assign a comment:
using (var zipFile = new ZipFile(zipFilePath))
{
var addDirectory = zipFile.AddDirectory(directoryPathToAdd, "directory");
addDirectory.Comment = "directory comment";
var zipEntries = zipFile.Entries
.Where(x => !x.IsDirectory)
.Where(x => x.FileName.StartsWith("directory"));
foreach (var zipentry in zipEntries)
zipentry.Comment = "zip entry comment";
zipFile.Save();
}
Hope it helps.

Related

Zip up collection of files and move to target location

I'm collecting all my files in a target directory and adding them to a zip folder. Once this zip is made and no more files need adding to it, I want to move this zip folder to another location.
Here is my code for doing all of the above:
var targetFolder = Path.Combine(ConfigurationManager.AppSettings["targetFolder"], "Inbound");
var archiveFolder = ConfigurationManager.AppSettings["ArchiveFolder"];
// get files
var files = Directory.GetFiles(targetFolder)
.Select(f => new FileInfo(f))
.ToList();
// places files into zip
using (var zip = ZipFile.Open("file.zip", ZipArchiveMode.Create))
{
foreach (var file in files)
{
var entry = zip.CreateEntry(file.Name);
entry.LastWriteTime = DateTimeOffset.Now;
using (var stream = File.OpenRead(file.ToString()))
using (var entryStream = entry.Open())
stream.CopyTo(entryStream);
}
}
// move the zip file
File.Move("file.zip", archiveFolder );
Where I'm falling down is the moving of the zip folder. When my code gets to File.Move I get an error telling me it can not create something that already exists. This happen even when I hard code in my archive folder location instead of getting it from my config.
What am I doing wrong with this?
You need to specify the destination file name as well as directory:
File.Move("file.zip", Path.Combine(archiveFolder, "file.zip"));

How to Extract ZIP file from specific path inside ZIP C# Ionic

I have one ZIP file named abc.ZIP
Inside ZIP folder structure is as below:
--abc
---pqr
----a
----b
----c
I want to extract this ZIP at D:/folder_name
But i want to extract only folder and its content named a,b,c. Also folder names are not fixed. I dont want to extract root folder abc and its child folder pqr.
I used following code but its not working:
using (ZipFile zipFile = ZipFile.Read(#"temp.zip"))
{
foreach (ZipEntry entry in zipFile.Entries)
{
entry.Extract(#"D:/folder_name");
}
}
The following should work, but I'm not sure, if it's the best option.
string rootPath = "abc/pqr/";
using (ZipFile zipFile = ZipFile.Read(#"abc.zip"))
{
foreach (ZipEntry entry in zipFile.Entries)
{
if (entry.FileName.StartsWith(rootPath) && entry.FileName.Length > rootPath.Length)
{
string path = Path.Combine(#"D:/folder_name", entry.FileName.Substring(rootPath.Length));
if (entry.IsDirectory)
{
Directory.CreateDirectory(path);
}
else
{
using (FileStream stream = new FileStream(path, FileMode.Create))
entry.Extract(stream);
}
}
}
}
Other option would be to extract the complete file in a temporary directory and move the sub directories to your target directory.

Get names of all files in path

I'm receiving an error Access to the path ... is denied when I attempt to read the files from a specified path. The code that demonstrates the error is below:
string path = "D:\\Study\\Прога 4 семестр\\Курсач\\tests";
StreamReader sr = new StreamReader(path);
while(!sr.EndOfStream)
{
string s = Path.GetFileNameWithoutExtension(path);
listBox1.Items.Add(s);
}
sr.Close();
What exactly is wrong with the code that an error occurs? How do I accomplish my goal?
Use Directory.EnumerateFiles to get all files in directory, and then project each file path to file name:
var names = Directory.EnumerateFiles(path)
.Select(f => Path.GetFileNameWithoutExtension(f));
Or even shorter way:
Directory.EnumerateFiles(path).Select(Path.GetFileNameWithoutExtension);
Unfortunately your using incorrect syntax. StreamReader will read a file, it will not retrieve a file. What you should do is use the Directory functionality from System.IO.
Example:
string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string[] files = Directory.GetFiles(path);
foreach(string item in files)
Console.WriteLine(item);
That would actually retrieve file data.
A secondary example:
var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var file = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
.Select(Path.GetFileName);
The Microsoft Developer Network has some terrific articles on different approaches to handle retrieval of files or directories from the system.
You can use Directory which has a method GetFiles(String) (+ 2 overloads) to enumerate and process files on older versions of .NET Frameworks.
string path = "D:\\Study\\Прога 4 семестр\\Курсач\\tests";
string[] fileNames = Directory.GetFiles(path);
for(int i = 0; i < fileNames.Length; i++)
{
string fileName = Path.GetFileNameWithoutExtension(path + "\\" + fileNames[i]);
listBox1.Items.Add(fileName);
}

C# - Search for Matching FileNames in a Directory using SearchOption

Background: I'm developing a WinForms application using C# with an OpenFileDialog & FileBrowserDialog that will 1) search for a specific string in the filenames of a specified source directory 2) copy files to consolidated directory 3) convert multiple files from excel to csv files, and then 3) convert all the generated csv files into 1 big csv file using a command line executable
Example: MSDN provides a code example that lists all of the directories and files that begin with the letter "c" in "c:\". at http://msdn.microsoft.com/en-us/library/ms143448.aspx so I based my code on that...
Problem: The code doesn't copy any files to the consolidated folder so I'm pretty sure the search doesn't work.
What should I change on here? It doesn't work :
string files = "*.xlsx";
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d, files))
{
// Is this the file we are looking for?
// check excel files for corp name in the filename.
if (f.Contains(m_sc.get_Corp()))
{
// check if thread is cancelled
if (m_EventStop.WaitOne(0, true))
{
// clean-up operations may be placed here
// ...
// inform main thread that this thread stopped
m_EventStopped.Set();
return;
}
else
{
string path = sDir;
string searchPattern = m_sc.get_Corp();
// A file has been found in this directory
DirectoryInfo di = new DirectoryInfo(path);
DirectoryInfo[] directories = di.GetDirectories(searchPattern, SearchOption.TopDirectoryOnly);
foreach (FileInfo file in files)
{
try
{
// Copy each selected xlsx files into the specified TargetFolder
System.IO.File.Copy(FileName, consolidatedFolder + #"\" + System.IO.Path.GetFileName(FileName));
Log("File" + FileName + " has been copied to " + consolidatedFolder + #"\" + System.IO.Path.GetFileName(sourceFileOpenFileDialog.FileName));
// Convert each selected XLSX File to CSV Using the command prompt code...
}
}
}
}
The code you've posted does two separate search loops:
first:
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d, files))
{
// Is this the file we are looking for?
// check excel files for corp name in the filename.
if (f.Contains(m_sc.get_Corp()))
{
then within that it also does:
string path = sDir;
string searchPattern = m_sc.get_Corp();
// A file has been found in this directory
DirectoryInfo di = new DirectoryInfo(path);
DirectoryInfo[] directories = di.GetDirectories(searchPattern, SearchOption.TopDirectoryOnly);
foreach (FileInfo file in files)
{
In the first one you are looking for files matching m_sc.get_Corp();, in the second one you are lookinf for directories...
In fact... your code (pseudo-code?) makes no sense...
Try:
taking your time
tidying up the code yourself
if you rewrite it slowly and break this into smaller chunks, you might spot what you are doing wrong.
Try cleaning up a bit, below is some code that will put you on the path, I've excluded the CSV conversion and the merge, hopefully you will get the idea.
private void YourFileRoutine(string sourceDirectoryPath, string consolidatedDirectoryPath)
{
var excelFiles = new DirectoryInfo(sourceDirectoryPath).GetFiles().Where(x => x.Extension == ".xlsx");
//Copy all Excel Files to consolidated Directory
foreach (var excelFile in excelFiles)
{
FileInfo copiedFile = excelFile.CopyTo(String.Concat(consolidatedDirectoryPath, excelFile.Name)); // Make sure consolidatedDirectoryPath as a "\" maybe use Path.Combine()?
// ConvertToCSV( Do your CSV conversion here, the Path will be = Path.GetFullPath(copiedFile);
}
// Merge CSV's
var csvFiles = new DirectoryInfo(consolidatedDirectoryPath).GetFiles().Where(x => x.Extension == ".csv");
// SomeMergeMethod that iterates through this FileInfo collection?
}

DotNetZip: How to extract files, but ignoring the path in the zipfile?

Trying to extract files to a given folder ignoring the path in the zipfile but there doesn't seem to be a way.
This seems a fairly basic requirement given all the other good stuff implemented in there.
What am i missing ?
code is -
using (Ionic.Zip.ZipFile zf = Ionic.Zip.ZipFile.Read(zipPath))
{
zf.ExtractAll(appPath);
}
While you can't specify it for a specific call to Extract() or ExtractAll(), the ZipFile class has a FlattenFoldersOnExtract field. When set to true, it flattens all the extracted files into one folder:
var flattenFoldersOnExtract = zip.FlattenFoldersOnExtract;
zip.FlattenFoldersOnExtract = true;
zip.ExtractAll();
zip.FlattenFoldersOnExtract = flattenFoldersOnExtract;
You'll need to remove the directory part of the filename just prior to unzipping...
using (var zf = Ionic.Zip.ZipFile.Read(zipPath))
{
zf.ToList().ForEach(entry =>
{
entry.FileName = System.IO.Path.GetFileName(entry.FileName);
entry.Extract(appPath);
});
}
You can use the overload that takes a stream as a parameter. In this way you have full control of path where the files will be extracted to.
Example:
using (ZipFile zip = new ZipFile(ZipPath))
{
foreach (ZipEntry e in zip)
{
string newPath = Path.Combine(FolderToExtractTo, e.FileName);
if (e.IsDirectory)
{
Directory.CreateDirectory(newPath);
}
else
{
using (FileStream stream = new FileStream(newPath, FileMode.Create))
e.Extract(stream);
}
}
}
That will fail if there are 2 files with equal filenames. For example
files\additionalfiles\file1.txt
temp\file1.txt
First file will be renamed to file1.txt in the zip file and when the second file is trying to be renamed an exception is thrown saying that an item with the same key already exists

Categories

Resources