You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
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;
using SharpCompress.Compressors;
using SharpCompress.Archives;
using SharpCompress.Archives.Zip;
using SharpCompress.Archives.Rar;
using SharpCompress.Archives.GZip;
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)
{
if (string.IsNullOrWhiteSpace(fileName))
{
throw new ArgumentNullException($"{fileName}");
}
if (!File.Exists(fileName))
{
throw new FileNotFoundException($"{fileName} not found");
}
try
{
//扩展名
var extName = Path.GetExtension(fileName).Trim().ToLower();
//文件名
var rarFileName = Path.GetFileName(fileName);
//不带扩展名的文件名
var rarFileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName);
//解压根目录
string extractPath = Path.GetDirectoryName(fileName) ?? "";
//解压文件
using (var archive = GetArchiveByExtName(fileName))
{
//创建解压目录
if (!Directory.Exists(extractPath))
{
Directory.CreateDirectory(extractPath);
}
//解压所有文件到指定目录
foreach (var entry in archive.Entries)
{
if (!entry.IsDirectory)
{
entry.WriteToDirectory(extractPath, new ExtractionOptions { ExtractFullPath = true, Overwrite = true });
}
}
//如果整体解压到一个同名目录,则把同名目录内容提取到当前目录,并删除同名目录
if (archive.Entries.Where(f => f.IsDirectory && f.Key == rarFileNameWithoutExt).Count() == 1)
{
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 && File.Exists(fileName))
{
File.Delete(fileName);
}
}
catch (Exception ex)
{
Console.Write($"解压报错,错误:{ex}");
throw;
}
}
/// <summary>
/// 按扩展名获取IArchive对象
/// </summary>
/// <param name="compressFileName">压缩文件</param>
/// <returns>IArchive对象</returns>
/// <exception cref="ArchiveException">压缩文件类型不支持异常</exception>
private static IArchive GetArchiveByExtName(string compressFileName)
{
IArchive archive;
var extName = Path.GetExtension(compressFileName).Trim().ToLower();
switch (extName)
{
case ".rar":
archive = RarArchive.Open(compressFileName);
break;
case ".zip":
archive = ZipArchive.Open(compressFileName);
break;
case ".7z":
archive = SevenZipArchive.Open(compressFileName);
break;
case ".gz":
archive = GZipArchive.Open(compressFileName);
break;
case ".tar":
archive = TarArchive.Open(compressFileName);
break;
default:
throw new ArchiveException($"不支持的压缩文件格式[{compressFileName}]");
}
return archive;
}
}
}