17 using System.Collections.Generic;
18 using System.Diagnostics;
20 using System.IO.Compression;
23 using System.Threading.Tasks;
24 using ICSharpCode.SharpZipLib.Core;
25 using ICSharpCode.SharpZipLib.GZip;
26 using ICSharpCode.SharpZipLib.Tar;
29 using ZipEntry = ICSharpCode.SharpZipLib.Zip.ZipEntry;
30 using ZipFile = Ionic.Zip.ZipFile;
31 using ZipInputStream = ICSharpCode.SharpZipLib.Zip.ZipInputStream;
32 using ZipOutputStream = ICSharpCode.SharpZipLib.Zip.ZipOutputStream;
45 private static bool IsLinux
49 var p = (int)Environment.OSVersion.Platform;
50 return (p == 4) || (p == 6) || (p == 128);
60 public static bool ZipData(
string zipPath, Dictionary<string, string> filenamesAndData)
65 using (var stream =
new ZipOutputStream(File.Create(zipPath)))
68 foreach (var kvp
in filenamesAndData)
70 var filename = kvp.Key;
72 var entry =
new ZipEntry(filename);
73 var bytes = Encoding.Default.GetBytes(kvp.Value);
74 stream.PutNextEntry(entry);
75 stream.Write(bytes, 0, bytes.Length);
98 public static bool ZipData(
string zipPath, IEnumerable<KeyValuePair<
string,
byte[]>> filenamesAndData)
101 var buffer =
new byte[4096];
106 using (var stream =
new ZipOutputStream(File.Create(zipPath)))
108 foreach (var file
in filenamesAndData)
111 var entry =
new ZipEntry(file.Key);
113 stream.PutNextEntry(entry);
115 using (var ms =
new MemoryStream(file.Value))
120 sourceBytes = ms.Read(buffer, 0, buffer.Length);
121 stream.Write(buffer, 0, sourceBytes);
123 while (sourceBytes > 0);
132 catch (Exception err)
147 public static bool ZipData(
string zipPath,
string zipEntry, IEnumerable<string> lines)
151 using (var stream =
new ZipOutputStream(File.Create(zipPath)))
152 using (var writer =
new StreamWriter(stream))
154 var entry =
new ZipEntry(zipEntry);
155 stream.PutNextEntry(entry);
156 foreach (var line
in lines)
158 writer.WriteLine(line);
163 catch (Exception err)
178 public static bool ZipCreateAppendData(
string path,
string entry,
string data,
bool overrideEntry =
false)
182 using (var zip = File.Exists(path) ? ZipFile.Read(path) :
new ZipFile(path))
184 if (zip.ContainsEntry(entry) && overrideEntry)
186 zip.RemoveEntry(entry);
189 zip.AddEntry(entry, data);
190 zip.UseZip64WhenSaving = Zip64Option.Always;
194 catch (Exception err)
210 public static bool ZipCreateAppendData(
string path,
string entry,
byte[] data,
bool overrideEntry =
false)
214 using (var zip = File.Exists(path) ? ZipFile.Read(path) :
new ZipFile(path))
216 if (overrideEntry && zip.ContainsEntry(entry))
218 zip.RemoveEntry(entry);
221 zip.AddEntry(entry, data);
222 zip.UseZip64WhenSaving = Zip64Option.Always;
226 catch (Exception err)
228 Log.
Error(err, $
"file: {path} entry: {entry}");
240 public static Dictionary<string, string>
UnzipData(
byte[] zipData, Encoding encoding =
null)
242 using var stream =
new MemoryStream(zipData);
243 return UnzipDataAsync(stream, encoding).ConfigureAwait(
false).GetAwaiter().GetResult();
252 public static async Task<Dictionary<string, string>>
UnzipDataAsync(Stream stream, Encoding encoding =
null)
255 var data =
new Dictionary<string, string>();
260 using (var zipStream =
new ZipInputStream(stream))
265 var entry = zipStream.GetNextEntry();
270 var buffer =
new byte[entry.Size];
271 await zipStream.ReadAsync(buffer, 0, (
int)entry.Size).ConfigureAwait(
false);
274 var str = (encoding ?? Encoding.ASCII).GetString(buffer);
275 data[entry.Name] = str;
285 catch (Exception err)
298 public static byte[]
ZipBytes(
byte[] bytes,
string zipEntryName)
300 using (var memoryStream =
new MemoryStream())
302 using (var archive =
new ZipArchive(memoryStream, ZipArchiveMode.Create,
true))
304 var entry = archive.CreateEntry(zipEntryName);
305 using (var entryStream = entry.Open())
307 entryStream.Write(bytes, 0, bytes.Length);
311 return memoryStream.ToArray();
320 public static string UnGZip(
string gzipFileName,
string targetDirectory)
323 var dataBuffer =
new byte[4096];
324 var newFileOutput = Path.Combine(targetDirectory, Path.GetFileNameWithoutExtension(gzipFileName));
325 using (Stream fileStream =
new FileStream(gzipFileName, FileMode.Open, FileAccess.Read))
326 using (var gzipStream =
new GZipInputStream(fileStream))
327 using (var fileOutput = File.Create(newFileOutput))
329 StreamUtils.Copy(gzipStream, fileOutput, dataBuffer);
331 return newFileOutput;
341 public static string Zip(
string textPath,
string zipEntryName,
bool deleteOriginal =
true)
343 var zipPath = textPath.Replace(
".csv",
".zip").Replace(
".txt",
".zip");
344 Zip(textPath, zipPath, zipEntryName, deleteOriginal);
355 public static void Zip(
string source,
string destination,
string zipEntryName,
bool deleteOriginal)
359 var buffer =
new byte[4096];
360 using (var stream =
new ZipOutputStream(File.Create(destination)))
363 var entry =
new ZipEntry(zipEntryName);
364 stream.PutNextEntry(entry);
366 using (var fs = File.OpenRead(source))
371 sourceBytes = fs.Read(buffer, 0, buffer.Length);
372 stream.Write(buffer, 0, sourceBytes);
374 while (sourceBytes > 0);
384 catch (Exception err)
396 public static string Zip(
string textPath,
bool deleteOriginal =
true)
398 return Zip(textPath, Path.GetFileName(textPath), deleteOriginal);
407 public static void Zip(
string data,
string zipPath,
string zipEntry)
409 using (var stream =
new ZipOutputStream(File.Create(zipPath)))
411 var entry =
new ZipEntry(zipEntry);
412 stream.PutNextEntry(entry);
413 var buffer =
new byte[4096];
414 using (var dataReader =
new MemoryStream(Encoding.Default.GetBytes(data)))
419 sourceBytes = dataReader.Read(buffer, 0, buffer.Length);
420 stream.Write(buffer, 0, sourceBytes);
422 while (sourceBytes > 0);
434 public static bool ZipDirectory(
string directory,
string destination,
bool includeRootInZip =
true)
438 if (File.Exists(destination)) File.Delete(destination);
439 System.IO.Compression.ZipFile.CreateFromDirectory(directory, destination, CompressionLevel.Fastest, includeRootInZip,
new PathEncoder());
442 catch (Exception err)
452 private class PathEncoder : UTF8Encoding
454 public override byte[] GetBytes(
string s)
456 s = s.Replace(
"\\",
"/");
457 return base.GetBytes(s);
467 public static bool Unzip(
string zip,
string directory,
bool overwrite =
false)
469 if (!File.Exists(zip))
return false;
475 System.IO.Compression.ZipFile.ExtractToDirectory(zip, directory);
479 using (var archive =
new ZipArchive(File.OpenRead(zip)))
481 foreach (var file
in archive.Entries)
484 if (
string.IsNullOrEmpty(file.Name))
continue;
485 var filepath = Path.Combine(directory, file.FullName);
486 if (IsLinux) filepath = filepath.Replace(
@"\",
"/");
487 var outputFile =
new FileInfo(filepath);
488 if (!outputFile.Directory.Exists)
490 outputFile.Directory.Create();
492 file.ExtractToFile(outputFile.FullName,
true);
499 catch (Exception err)
509 public static void ZipFiles(
string destination, IEnumerable<string> files)
513 using (var zipStream =
new ZipOutputStream(File.Create(destination)))
515 var buffer =
new byte[4096];
516 foreach (var file
in files)
518 if (!File.Exists(file))
520 Log.
Trace($
"ZipFiles(): File does not exist: {file}");
524 var entry =
new ZipEntry(Path.GetFileName(file));
525 zipStream.PutNextEntry(entry);
526 using (var fstream = File.OpenRead(file))
528 StreamUtils.Copy(fstream, zipStream, buffer);
533 catch (Exception err)
546 public static StreamReader
Unzip(
string filename, out ZipFile zip)
548 return Unzip(filename,
null, out zip);
559 public static StreamReader
Unzip(
string filename,
string zipEntryName, out ZipFile zip)
561 StreamReader reader =
null;
566 if (File.Exists(filename))
570 zip =
new ZipFile(filename);
571 var entry = zip.FirstOrDefault(x => zipEntryName ==
null ||
string.Compare(x.FileName, zipEntryName, StringComparison.OrdinalIgnoreCase) == 0);
578 reader =
new StreamReader(entry.OpenReader());
580 catch (Exception err)
583 if (zip !=
null) zip.Dispose();
584 if (reader !=
null) reader.Close();
589 Log.
Error($
"Data.UnZip(2): File doesn\'t exist: {filename}");
592 catch (Exception err)
594 Log.
Error(err,
"File: " + filename);
610 public static IEnumerable<KeyValuePair<string, List<string>>>
Unzip(
string filename)
612 if (!File.Exists(filename))
614 Log.
Error($
"Compression.Unzip(): File does not exist: {filename}");
615 return Enumerable.Empty<KeyValuePair<string, List<string>>>();
620 return ReadLinesImpl(filename);
622 catch (Exception err)
626 return Enumerable.Empty<KeyValuePair<string, List<string>>>();
635 public static IEnumerable<KeyValuePair<string, List<string>>>
Unzip(Stream stream)
637 using (var zip = ZipFile.Read(stream))
639 foreach (var entry
in zip)
641 yield
return new KeyValuePair<string, List<string>>(entry.FileName, ReadZipEntry(entry));
653 if (!File.Exists(filename))
655 Log.
Error($
"Compression.ReadFirstZipEntry(): File does not exist: {filename}");
656 return new List<string>();
661 return ReadLinesImpl(filename, firstEntryOnly:
true).Single().Value;
663 catch (Exception err)
667 return new List<string>();
670 private static IEnumerable<KeyValuePair<string, List<string>>> ReadLinesImpl(
string filename,
bool firstEntryOnly =
false)
672 using (var zip = ZipFile.Read(filename))
674 for (var i = 0; i < zip.Count; i++)
677 yield
return new KeyValuePair<string, List<string>>(entry.FileName, ReadZipEntry(entry));
686 private static List<string> ReadZipEntry(Ionic.Zip.ZipEntry entry)
688 var result =
new List<string>();
689 using var entryReader =
new StreamReader(entry.OpenReader());
690 var line = entryReader.ReadLine();
694 line = entryReader.ReadLine();
704 StreamReader reader =
null;
711 using (var zipStream =
new ZipInputStream(zipstream))
714 var entry = zipStream.GetNextEntry();
715 var buffer =
new byte[entry.Size];
716 zipStream.Read(buffer, 0, (
int)entry.Size);
719 file =
new MemoryStream(buffer);
723 reader =
new StreamReader(file);
725 catch (Exception err)
736 public static Stream
UnzipStream(Stream zipstream, out ZipFile zipFile,
string entryName =
null)
738 zipFile = ZipFile.Read(zipstream);
742 Ionic.Zip.ZipEntry entry;
743 if (
string.IsNullOrEmpty(entryName))
746 entry = zipFile.Entries.FirstOrDefault();
751 if (!zipFile.ContainsEntry(entryName))
755 entry = zipFile[entryName];
760 return entry.OpenReader();
763 catch (Exception err)
777 public static List<string>
UnzipToFolder(
byte[] zipData,
string outputFolder)
779 var stream =
new MemoryStream(zipData);
790 var outFolder = Path.GetDirectoryName(zipFile);
791 var stream = File.OpenRead(zipFile);
801 private static List<string>
UnzipToFolder(Stream dataStream,
string outFolder)
804 var files =
new List<string>();
805 if (
string.IsNullOrEmpty(outFolder))
807 outFolder = Directory.GetCurrentDirectory();
809 ICSharpCode.SharpZipLib.Zip.ZipFile zf =
null;
813 zf =
new ICSharpCode.SharpZipLib.Zip.ZipFile(dataStream);
815 foreach (ZipEntry zipEntry
in zf)
818 if (!zipEntry.IsFile)
continue;
820 var buffer =
new byte[4096];
821 var zipStream = zf.GetInputStream(zipEntry);
824 var fullZipToPath = Path.Combine(outFolder, zipEntry.Name);
826 var targetFile =
new FileInfo(fullZipToPath);
827 if (targetFile.Directory !=
null && !targetFile.Directory.Exists)
829 targetFile.Directory.Create();
833 files.Add(fullZipToPath);
836 using (var streamWriter =
File.Create(fullZipToPath))
838 StreamUtils.Copy(zipStream, streamWriter, buffer);
845 Log.
Error($
"Compression.UnzipToFolder(): Failure: outFolder: {outFolder} - files: {string.Join(",
", files)}");
852 zf.IsStreamOwner =
true;
864 public static void UnTarFiles(
string source,
string destination)
866 var inStream = File.OpenRead(source);
867 var tarArchive = TarArchive.CreateInputTarArchive(inStream);
868 tarArchive.ExtractContents(destination);
880 var inStream = File.OpenRead(source);
881 var gzipStream =
new GZipInputStream(inStream);
882 var tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
883 tarArchive.ExtractContents(destination);
895 public static IEnumerable<KeyValuePair<string, byte[]>>
UnTar(Stream stream,
bool isTarGz)
897 using (var tar =
new TarInputStream(isTarGz ? (Stream)
new GZipInputStream(stream) : stream))
900 while ((entry = tar.GetNextEntry()) !=
null)
902 if (entry.IsDirectory)
continue;
904 using (var output =
new MemoryStream())
906 tar.CopyEntryContents(output);
907 yield
return new KeyValuePair<string, byte[]>(entry.Name, output.ToArray());
918 public static IEnumerable<KeyValuePair<string, byte[]>>
UnTar(
string source)
921 var gzip = (source.Substring(Math.Max(0, source.Length - 6)) ==
"tar.gz");
923 using (var file = File.OpenRead(source))
925 var tarIn =
new TarInputStream(file);
929 var gzipStream =
new GZipInputStream(file);
930 tarIn =
new TarInputStream(gzipStream);
934 while ((tarEntry = tarIn.GetNextEntry()) !=
null)
936 if (tarEntry.IsDirectory)
continue;
938 using (var stream =
new MemoryStream())
940 tarIn.CopyEntryContents(stream);
941 yield
return new KeyValuePair<string, byte[]>(tarEntry.Name, stream.ToArray());
955 using (var zip =
new ICSharpCode.SharpZipLib.Zip.ZipFile(path))
957 return zip.TestArchive(
true);
968 using (var zip = ZipFile.Read(zipFileName))
970 return zip.EntryFileNames;
981 using (var zip = ZipFile.Read(zipFileStream))
983 return zip.EntryFileNames;
994 public static void Extract7ZipArchive(
string inputFile,
string outputDirectory,
int execTimeout = 60000)
996 var zipper = IsLinux ?
"7z" :
"C:/Program Files/7-Zip/7z.exe";
997 var psi =
new ProcessStartInfo(zipper,
" e " + inputFile +
" -o" + outputDirectory)
999 CreateNoWindow =
true,
1000 WindowStyle = ProcessWindowStyle.Hidden,
1001 UseShellExecute =
false,
1002 RedirectStandardOutput =
false
1005 var process =
new Process();
1006 process.StartInfo = psi;
1009 if (!process.WaitForExit(execTimeout))
1011 throw new TimeoutException($
"Timed out extracting 7Zip archive: {inputFile} ({execTimeout} seconds)");
1013 if (process.ExitCode > 0)
1015 throw new Exception($
"Compression.Extract7ZipArchive(): 7Zip exited unsuccessfully (code {process.ExitCode})");