|
|
|
@ -1,13 +1,12 @@
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.IO.Compression;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Text.Unicode;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using SharpCompress;
|
|
|
|
|
using SharpCompress.Common;
|
|
|
|
|
using SharpCompress.Factories;
|
|
|
|
|
using SharpCompress.Writers;
|
|
|
|
@ -21,168 +20,133 @@ using SharpCompress.Archives.Tar;
|
|
|
|
|
using SharpCompress.Archives.SevenZip;
|
|
|
|
|
using SharpCompress.Readers;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace SharpCompressStudy.Core
|
|
|
|
|
{
|
|
|
|
|
public static class CommonUtility
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 解压文件
|
|
|
|
|
/// (解压到压缩文件所在目录)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="fileName">压缩文件包</param>
|
|
|
|
|
/// <param name="isDelete">解压后删除压缩文件</param>
|
|
|
|
|
public static void Decompress(string fileName, bool isDelete)
|
|
|
|
|
{
|
|
|
|
|
var extName = Path.GetExtension(fileName).Trim().ToLower();
|
|
|
|
|
switch (extName)
|
|
|
|
|
{
|
|
|
|
|
case ".rar":
|
|
|
|
|
DecompressRarFile(fileName, isDelete);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ".zip":
|
|
|
|
|
DecompressZipFile(fileName, isDelete);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ".gzip":
|
|
|
|
|
DecompressGzipFile(fileName, isDelete);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ".gz":
|
|
|
|
|
DecompressGzFile(fileName, isDelete);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isDelete)
|
|
|
|
|
if (string.IsNullOrWhiteSpace(fileName))
|
|
|
|
|
{
|
|
|
|
|
File.Delete(fileName);
|
|
|
|
|
throw new ArgumentNullException($"{fileName}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void DecompressRarFile(string fileName, bool isDelete)
|
|
|
|
|
{
|
|
|
|
|
ArgumentNullException.ThrowIfNull(fileName);
|
|
|
|
|
|
|
|
|
|
var extName = Path.GetExtension(fileName);
|
|
|
|
|
|
|
|
|
|
var descDir = Path.Combine(Path.GetDirectoryName(fileName)!, new FileInfo(fileName).Name.Replace(extName,"") + "\\");
|
|
|
|
|
|
|
|
|
|
if (!Directory.Exists(descDir))
|
|
|
|
|
if (!File.Exists(fileName))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(descDir);
|
|
|
|
|
throw new FileNotFoundException($"{fileName} not found");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using (Stream stream = File.OpenRead(fileName))
|
|
|
|
|
{
|
|
|
|
|
var reader = ReaderFactory.Open(stream);
|
|
|
|
|
while (reader.MoveToNextEntry())
|
|
|
|
|
{
|
|
|
|
|
if (!reader.Entry.IsDirectory)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(reader.Entry.Key);
|
|
|
|
|
reader.WriteEntryToDirectory(descDir, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isDelete)
|
|
|
|
|
{
|
|
|
|
|
File.Delete(fileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.Write($"解压报错,错误:{ex}");
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//扩展名
|
|
|
|
|
var extName = Path.GetExtension(fileName).Trim().ToLower();
|
|
|
|
|
|
|
|
|
|
private static void DecompressZipFile(string fileName, bool isDelete)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ExtractionOptions options = new ExtractionOptions();
|
|
|
|
|
//文件名
|
|
|
|
|
var rarFileName = Path.GetFileName(fileName);
|
|
|
|
|
|
|
|
|
|
//抽取顶级目录
|
|
|
|
|
var extractPath = Directory.GetParent(fileName)?.FullName + "22";
|
|
|
|
|
if (!Directory.Exists(extractPath))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(extractPath);
|
|
|
|
|
}
|
|
|
|
|
//不带扩展名的文件名
|
|
|
|
|
var rarFileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName);
|
|
|
|
|
|
|
|
|
|
//解压根目录
|
|
|
|
|
string extractPath = Path.GetDirectoryName(fileName) ?? "";
|
|
|
|
|
|
|
|
|
|
var archive = ArchiveFactory.Open(fileName);
|
|
|
|
|
foreach (var entry in archive.Entries)
|
|
|
|
|
//解压文件
|
|
|
|
|
using (var archive = GetArchiveByExtName(fileName))
|
|
|
|
|
{
|
|
|
|
|
//加密的
|
|
|
|
|
if (entry.IsEncrypted)
|
|
|
|
|
//创建解压目录
|
|
|
|
|
if (!Directory.Exists(extractPath))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
Directory.CreateDirectory(extractPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (entry.IsDirectory)
|
|
|
|
|
//解压所有文件到指定目录
|
|
|
|
|
foreach (var entry in archive.Entries)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (!entry.IsDirectory)
|
|
|
|
|
{
|
|
|
|
|
entry.WriteToDirectory(extractPath, new ExtractionOptions { ExtractFullPath = true, Overwrite = true });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
//如果整体解压到一个同名目录,则把同名目录内容提取到当前目录,并删除同名目录
|
|
|
|
|
if (archive.Entries.Where(f => f.IsDirectory && f.Key == rarFileNameWithoutExt).Count() == 1)
|
|
|
|
|
{
|
|
|
|
|
entry.WriteToDirectory(extractPath, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true });
|
|
|
|
|
var dir = new DirectoryInfo(Path.Combine(extractPath, rarFileNameWithoutExt));
|
|
|
|
|
dir.GetDirectories().ForEach(f =>
|
|
|
|
|
{
|
|
|
|
|
var toDir = Path.Combine(extractPath, f.Name);
|
|
|
|
|
if (Directory.Exists(toDir))
|
|
|
|
|
{
|
|
|
|
|
Directory.Delete(toDir, true);
|
|
|
|
|
}
|
|
|
|
|
f.MoveTo(toDir);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
dir.GetFiles().ForEach(f =>
|
|
|
|
|
{
|
|
|
|
|
f.MoveTo(Path.Combine(extractPath, f.Name), true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
dir.Delete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isDelete)
|
|
|
|
|
//删除压缩文件
|
|
|
|
|
if (isDelete && File.Exists(fileName))
|
|
|
|
|
{
|
|
|
|
|
File.Delete(fileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.Write($"解压报错,错误:{ex.Message}");
|
|
|
|
|
Console.Write($"解压报错,错误:{ex}");
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void DecompressGzipFile(string fileName, bool isDelete)
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 按扩展名获取IArchive对象
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="compressFileName">压缩文件</param>
|
|
|
|
|
/// <returns>IArchive对象</returns>
|
|
|
|
|
/// <exception cref="ArchiveException">压缩文件类型不支持异常</exception>
|
|
|
|
|
private static IArchive GetArchiveByExtName(string compressFileName)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
IArchive archive;
|
|
|
|
|
var extName = Path.GetExtension(compressFileName).Trim().ToLower();
|
|
|
|
|
switch (extName)
|
|
|
|
|
{
|
|
|
|
|
case ".rar":
|
|
|
|
|
archive = RarArchive.Open(compressFileName);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (isDelete)
|
|
|
|
|
{
|
|
|
|
|
File.Delete(fileName);
|
|
|
|
|
}
|
|
|
|
|
case ".zip":
|
|
|
|
|
archive = ZipArchive.Open(compressFileName);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.Write($"解压报错,错误:{ex}");
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case ".7z":
|
|
|
|
|
archive = SevenZipArchive.Open(compressFileName);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
private static void DecompressGzFile(string fileName, bool isDelete)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (isDelete)
|
|
|
|
|
{
|
|
|
|
|
File.Delete(fileName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.Write($"解压报错,错误:{ex}");
|
|
|
|
|
throw;
|
|
|
|
|
case ".gz":
|
|
|
|
|
archive = GZipArchive.Open(compressFileName);
|
|
|
|
|
break;
|
|
|
|
|
case ".tar":
|
|
|
|
|
archive = TarArchive.Open(compressFileName);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
throw new ArchiveException($"不支持的压缩文件格式[{compressFileName}]");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return archive;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|