147 lines
5.8 KiB
C#
147 lines
5.8 KiB
C#
|
using System;
|
|||
|
using System.IO;
|
|||
|
using System.IO.Compression;
|
|||
|
|
|||
|
namespace Alkami.Ops.Common.FileSystem
|
|||
|
{
|
|||
|
public static class ZipHelpers
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// Unzip a path into a specific folder
|
|||
|
/// </summary>
|
|||
|
/// <param name="zipPath">Path of the file to unzip.</param>
|
|||
|
/// <param name="destinationDirectory">If null defaults to a new folder at current location with the Zip file's name.</param>
|
|||
|
public static void UnZip(string zipPath, string destinationDirectory = null)
|
|||
|
{
|
|||
|
if (!string.IsNullOrWhiteSpace(zipPath))
|
|||
|
{
|
|||
|
if (string.IsNullOrWhiteSpace(destinationDirectory))
|
|||
|
{
|
|||
|
destinationDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
|||
|
destinationDirectory = Path.Combine(destinationDirectory, Path.GetFileNameWithoutExtension(zipPath));
|
|||
|
}
|
|||
|
|
|||
|
Directory.CreateDirectory(destinationDirectory);
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
using (var archive = ZipFile.OpenRead(zipPath))
|
|||
|
{
|
|||
|
archive.ExtractToDirectory(destinationDirectory);
|
|||
|
}
|
|||
|
}
|
|||
|
catch (IOException ex)
|
|||
|
{
|
|||
|
Console.Error.WriteLine("Exception occurred while extracting files.");
|
|||
|
|
|||
|
Console.Error.WriteLine(ex);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Unzips a single directory from inside a zip file.
|
|||
|
/// </summary>
|
|||
|
/// <param name="zipPath">Path of the file to unzip.</param>
|
|||
|
/// <param name="internalDirectory">Directory inside of zip file to be extracted. If null or nonexistent nothing will be extracted.</param>
|
|||
|
/// <param name="destinationDirectory">If null defaults to a new folder at current location with the Zip subfolder's name.</param>
|
|||
|
public static void UnZipSubDirectory(string internalDirectory, string zipPath, string destinationDirectory = null)
|
|||
|
{
|
|||
|
if (!string.IsNullOrWhiteSpace(zipPath))
|
|||
|
{
|
|||
|
if (string.IsNullOrWhiteSpace(destinationDirectory))
|
|||
|
{
|
|||
|
destinationDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
|
|||
|
destinationDirectory = Path.Combine(destinationDirectory, Path.GetFileNameWithoutExtension(zipPath));
|
|||
|
}
|
|||
|
|
|||
|
Directory.CreateDirectory(destinationDirectory);
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
using (var archive = ZipFile.OpenRead(zipPath))
|
|||
|
{
|
|||
|
foreach (var entry in archive.Entries)
|
|||
|
{
|
|||
|
if (GetRootFolder(entry.FullName).IndexOf(internalDirectory, StringComparison.OrdinalIgnoreCase) >= 0)
|
|||
|
{
|
|||
|
ExtractEntry(entry, destinationDirectory, entry.FullName);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (IOException ex)
|
|||
|
{
|
|||
|
Console.Error.WriteLine("Exception occurred while extracting files.");
|
|||
|
|
|||
|
Console.Error.WriteLine(ex);
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
Console.Error.WriteLine("Unknown exception occurred while extracting files");
|
|||
|
|
|||
|
Console.Error.WriteLine(ex);
|
|||
|
|
|||
|
throw;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Recursively handle subfolders
|
|||
|
/// </summary>
|
|||
|
/// <param name="entry">Zip entry to extract</param>
|
|||
|
/// <param name="destinationDirectory">Desired destination directory. Is added to with each recursive loop as subdirectories are popped off of the entry</param>
|
|||
|
/// <param name="entryPath">Current entry path. Shorter every loop as we pop off directories and add them to the destinationDirectory parameter.</param>
|
|||
|
private static void ExtractEntry(ZipArchiveEntry entry, string destinationDirectory, string entryPath)
|
|||
|
{
|
|||
|
var targetIsDirectory = false;
|
|||
|
var topLevelDirectory = "";
|
|||
|
|
|||
|
if (!string.IsNullOrWhiteSpace(entryPath) && !entryPath.Equals('/'))
|
|||
|
{
|
|||
|
topLevelDirectory = Path.GetDirectoryName(entryPath);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
targetIsDirectory = true;
|
|||
|
}
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(topLevelDirectory))
|
|||
|
{
|
|||
|
Directory.CreateDirectory(Path.Combine(destinationDirectory, topLevelDirectory));
|
|||
|
destinationDirectory = Path.Combine(destinationDirectory, topLevelDirectory);
|
|||
|
ExtractEntry(entry, destinationDirectory, Path.GetFileName(entryPath));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (targetIsDirectory)
|
|||
|
{
|
|||
|
Directory.CreateDirectory(destinationDirectory);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
entry.ExtractToFile(Path.Combine(destinationDirectory, entry.Name));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Cargo culted from https://stackoverflow.com/a/40124633/3691973
|
|||
|
/// </summary>
|
|||
|
/// <param name="path">Path to examine</param>
|
|||
|
/// <returns>Top level folder.</returns>
|
|||
|
private static string GetRootFolder(string path)
|
|||
|
{
|
|||
|
var root = Path.GetPathRoot(path);
|
|||
|
while (true)
|
|||
|
{
|
|||
|
var temp = Path.GetDirectoryName(path);
|
|||
|
if (temp != null && temp.Equals(root))
|
|||
|
break;
|
|||
|
path = temp;
|
|||
|
}
|
|||
|
return path;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|