Unzip all .zip archives in a directory - c#

I am struggling to configure a script to unzip all .zip archives in a directory and place the extracted files into a different directory. I am wanting to schedule this script to run on a schedule to handle incoming .zip archives.
For each .zip file in the source directory, I need it to extract those files to the destination, then repeat until all .zip files have been processed.
Here is my horrible attempt.
using System;
using System.IO;
using System.IO.Compression;
namespace Unzipper
{
class Program
{
static void Main(string[] args)
{
string startPath = #"C:\zipdirectory\";
foreach(String file in Directory.GetFiles(startPath, "*.zip", SearchOptions.AllDirectories)){allFiles.Add(file);
string zipPath = #"(output from above??)
string extractPath = #"C:\unzipdirectory\";
ZipFile.ExtractToDirectory(zipPath, extractPath);
}
}
}

Firstly, you get all .zip file in the startPath
For each path, unzip it to a new folder created by a combination like C:\unzipdirectory\<zip_file_name_without_extension_zip>
static void Main(string[] args)
{
string startPath = #"C:\zipdirectory\";
string extractPath = #"C:\unzipdirectory\";
Directory.GetFiles(startPath, "*.zip", SearchOptions.AllDirectories).ToList()
.ForEach(zipFilePath => {
var extractPathForCurrentZip = Path.Combine(extractPath, Path.GetFileNameWithoutExtension(zipFilePath));
if(!Directory.Exists(extractPathForCurrentZip))
{
Directory.CreateDirectory(extractPathForCurrentZip);
}
ZipFile.ExtractToDirectory(zipFilePath, extractPathForCurrentZip);
});
}

Related

Display files in a folder to a CSV using C#

Is there a simple way to display the files in a folder to a CSV that shows whether the files in that folder are JPG, PDF, or other using C#?
There is no built-in way to do this in C#, but you can use the System.IO.Directory and System.IO.File classes to get a list of files in a directory and then check their extensions to see if they are JPG, PDF, or other.
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
string directory = "C:\\";
string[] files = Directory.GetFiles(directory);
using (StreamWriter writer = new StreamWriter("files.csv"))
{
foreach (string file in files)
{
string extension = Path.GetExtension(file);
writer.WriteLine("{0},{1}", file, extension);
}
}
}
}
You can use Matcher to traverse a folder structure using wild cards to getting specific file types and exclusions also.
Example method
public static async Task Demo(string parentFolder, string[] patterns, string[] excludePatterns, string fileName)
{
StringBuilder builder = new StringBuilder();
Matcher matcher = new();
matcher.AddIncludePatterns(patterns);
matcher.AddExcludePatterns(excludePatterns);
await Task.Run(() =>
{
foreach (string file in matcher.GetResultsInFullPath(parentFolder))
{
builder.AppendLine(file);
}
});
await File.WriteAllTextAsync("TODO", builder.ToString());
}
Example call, find all png and pdf files but exclude some specified in the exclude array which is explained in the docs.
string[] include = { "**/*.png", "**/*.pdf" };
string[] exclude = { "**/*in*.png", "**/*or*.png" };
await GlobbingOperations.Demo(
"Parent folder",
include,
exclude,
"Dump.txt");
When traversing files add any other logic to get specifics about a file and use that to add to the builder variable for writing to a file.

how to upload files with its original folder structure in blob storage?

below code will upload files to blob storage
// intialize BobClient
Azure.Storage.Blobs.BlobClient blobClient = new Azure.Storage.Blobs.BlobClient(
connectionString: connectionString,
blobContainerName: "mycrmfilescontainer",
blobName: "sampleBlobFileTest");
// upload the file
blobClient.Upload(filePath);
but how to upload all files and maintain its folder structure as well?
I have site folder which includes all html files + images + css folder and inside that relative files of website.
I want to upload that complete site folder over on blob storage kindly suggest approch.
Please take a look at the code below:
using System.Threading.Tasks;
using System.IO;
using Azure.Storage.Blobs.Specialized;
namespace SO71558769
{
class Program
{
private const string connectionString = "connection-string";
private const string containerName = "container-name";
private const string directoryPath = "C:\temp\site\";
static async Task Main(string[] args)
{
var files = Directory.GetFiles(directoryPath, "*.*", SearchOption.AllDirectories);
for (var i=0; i<files.Length; i++)
{
var file = files[i];
var blobName = file.Replace(directoryPath, "").Replace("\\", "/");
BlockBlobClient blobClient = new BlockBlobClient(connectionString, containerName, blobName);
using (var fs = File.Open(file, FileMode.Open))
{
await blobClient.UploadAsync(fs);
}
}
}
}
}
Essentially the idea is to get the list of all files in the folder and then loop over that collection and upload each file.
To get the blob name, you would simply find the directory path in the file name and replace it with an empty string to get the blob name (e.g. if full file path is C:\temp\site\html\index.html, then the blob name would be `html\index.html).
If you are on Windows, then you would further need to replace \ delimiter with / delimiter so that you get the final blob name as html/index.html.

C# -Make a zip file from List of file paths

I have a number of folders and I have number of file in each folders.
I am taking some of the file paths from different folders and I need to zip those files into a single zip file.
if I have the file in a single folder, I can do zip using
string startPath = #"c:\example\start";//folder to add
string zipPath = #"c:\example\result.zip";//URL for your ZIP file
ZipFile.CreateFromDirectory(startPath, zipPath, CompressionLevel.Fastest, true);
string extractPath = #"c:\example\extract";//path to extract
ZipFile.ExtractToDirectory(zipPath, extractPath);
using (ZipArchive newFile = ZipFile.Open(zipName, ZipArchiveMode.Create))
{
foreach (string file in Directory.GetFiles(myPath))
{
newFile.CreateEntryFromFile(file);
}
}
Suppose I don't know about the folders, I only have a list of file paths, I need to foreach through each file path and add into the zip. What should I do for this?
You can enumerate all files in the directory include subdirectories with Directory.GetFiles overloading and SearchOption.AllDirectories option and then use it
String[] allfiles = System.IO.Directory.GetFiles("myPath", "*.*", System.IO.SearchOption.AllDirectories);
foreach (string file in allfiles)
{
newFile.CreateEntryFromFile(file);
}
You can use ZipFile.CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName) or its overload to create an archive in one step too.
Also there is a way to manipulate zip archive structure more flexibly via Path.GetDirectoryName() method. Here is the example:
foreach(var filePath in files)
{
var directory = Path.GetDirectoryName(filePath);
var fileName = Path.GetFileName(filePath);
var entry = archive.GetEntryFromFile(filePath, $"{directory}/{fileName}");
}
Finally, you can use 3rd party library DotNetZip and solve yor scenario in just 3 lines of code:
using (ZipFile zip = new ZipFile())
{
zip.AddFiles(files);
zip.Save("Archive.zip");
}
Using the DotNetZip library from newget manager, just check whether it will work or not
using (ZipFile zip = new ZipFile())
{
foreach(var filestring in AllFileArray)
{
zip.AddFile(filestring);
}
zip.save("MyZipFile.zip")
}

Zip file using C#

I want to zip one "CSV" file in to Zip file using C#.Net. Below i have written some code for create Zip file , using this code i am able to create zip file but after creating "Data1.zip" file extract manually means extracted file extension should be ".csv" but it is not coming.
FileStream sourceFile = File.OpenRead(#"C:\Users\Rav\Desktop\rData1.csv");
FileStream destFile = File.Create(#"C:\Users\Rav\Desktop\Data1.zip");
GZipStream compStream = new GZipStream(destFile, CompressionMode.Compress,false);
try
{
int theByte = sourceFile.ReadByte();
while (theByte != -1)
{
compStream.WriteByte((byte)theByte);
theByte = sourceFile.ReadByte();
}
}
finally
{
compStream.Dispose();
}
http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx
This is gzip compression, and apparently it only compresses a stream, which when decompressed takes the name of the archive without the .gz extension. I don't know if I'm right here though. You might as well experiment with the code from MSDN, see if it works.
I used ZipLib for zip compression. It also supports Bz2, which is a good compression algorithm.
Use ICSharpCode.SharpZipLib(you can download it) and do the following
private void CreateZipFile(string l_sFolderToZip)
{
FastZip z = new FastZip();
z.CreateEmptyDirectories = true;
z.CreateZip(l_sFolderToZip + ".zip", l_sFolderToZip, true, "");
if (Directory.Exists(l_sFolderToZip))
Directory.Delete(l_sFolderToZip, true);
}
private void ExtractFromZip(string l_sFolderToExtract)
{
string l_sZipPath ="ur folder path" + ".zip";
string l_sDestPath = "ur location" + l_sFolderToExtract;
FastZip z = new FastZip();
z.CreateEmptyDirectories = true;
z.ExtractZip(l_sZipPath, l_sDestPath, "");
if (File.Exists(l_sZipPath))
File.Delete(l_sZipPath);
}
Hope it helps...
Use one of these libraries:
http://www.icsharpcode.net/opensource/sharpziplib/
http://dotnetzip.codeplex.com/
I prefer #ziplib, but both are well documented and widely spread.
Since .NET Framework 4.5, you can use the built-in ZipFile class (In the System.IO.Compression namespace).
public void ZipFiles(string[] filePaths, string zipFilePath)
{
ZipArchive zipArchive = ZipFile.Open(zipFilePath, ZipArchiveMode.Create);
foreach (string file in filePaths)
{
zipArchive.CreateEntryFromFile(file, Path.GetFileName(file), CompressionLevel.Optimal);
}
zipArchive.Dispose();
}
Take a look at the FileSelectionManager library here: www.fileselectionmanager.com
First you have to add File Selection Manager DLL to your project
Here is an example for zipping:
class Program
{
static void Main(string[] args)
{
String directory = #"C:\images";
String destinationDiretory = #"c:\zip_files";
String zipFileName = "container.zip";
Boolean recursive = true;
Boolean overWrite = true;
String condition = "Name Contains \"uni\"";
FSM FSManager = new FSM();
/* creates zipped file containing selected files */
FSManager.Zip(directory,recursive,condition,destinationDirectory,zipFileName,overWrite);
Console.WriteLine("Involved Files: {0} - Affected Files: {1} ",
FSManager.InvolvedFiles,
FSManager.AffectedFiles);
foreach(FileInfo file in FSManager.SelectedFiles)
{
Console.WriteLine("{0} - {1} - {2} - {3} - {4} Bytes",
file.DirectoryName,
file.Name,
file.Extension,
file.CreationTime,
file.Length);
}
}
}
Here is an example for unzipping:
class Program
{
static void Main(string[] args)
{
String destinationDiretory = #"c:\zip_files";
String zipFileName = "container.zip";
Boolean unZipWithDirectoryStructure = true;
FSM FSManager = new FSM();
/* Unzips files with or without their directory structure */
FSManager.Unzip(zipFileName,
destinationDirectory,
unZipWithDirectoryStructure);
}
}
Hope it helps.
I use the dll fileselectionmanager to compress and decompress files and folders, it has worked properly in my project. You can see example in your web http://www.fileselectionmanager.com/#Zipping and Unzipping files
and documentation http://www.fileselectionmanager.com/file_selection_manager_documentation

How do I prevent this System.IO.IOException when copying a file?

When I run the following code to test copying a directory, I get a System.IO.IOException when fileInfo.CopyTo method is being called. The error message is: "The process cannot access the file 'C:\CopyDirectoryTest1\temp.txt' because it is being used by another process."
It seems like there's a lock on file1 ("C:\CopyDirectoryTest1\temp.txt") which is created a few lines above where the error is occurring, but I don't know how to release this if so. Any ideas?
using System;
using System.IO;
namespace TempConsoleApp
{
class Program
{
static void Main(string[] args)
{
string folder1 = #"C:\CopyDirectoryTest1";
string folder2 = #"C:\CopyDirectoryTest2";
string file1 = Path.Combine(folder1, "temp.txt");
if (Directory.Exists(folder1))
Directory.Delete(folder1, true);
if (Directory.Exists(folder2))
Directory.Delete(folder2, true);
Directory.CreateDirectory(folder1);
Directory.CreateDirectory(folder2);
File.Create(file1);
DirectoryInfo folder1Info = new DirectoryInfo(folder1);
DirectoryInfo folder2Info = new DirectoryInfo(folder2);
foreach (FileInfo fileInfo in folder1Info.GetFiles())
{
string fileName = fileInfo.Name;
string targetFilePath = Path.Combine(folder2Info.FullName, fileName);
fileInfo.CopyTo(targetFilePath, true);
}
}
}
}
File.Create returns an open FileStream - you need to close that stream.
Just
using (File.Create(file1)) {}
should do the trick.

Categories