main
wanggaofeng
parent 2327b62d67
commit f40f1c9a23

@ -1,13 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.Unicode; using System.Text.Unicode;
using System.Threading.Tasks; using System.Threading.Tasks;
using SharpCompress;
using SharpCompress.Common; using SharpCompress.Common;
using SharpCompress.Factories; using SharpCompress.Factories;
using SharpCompress.Writers; using SharpCompress.Writers;
@ -21,168 +20,133 @@ using SharpCompress.Archives.Tar;
using SharpCompress.Archives.SevenZip; using SharpCompress.Archives.SevenZip;
using SharpCompress.Readers; using SharpCompress.Readers;
namespace SharpCompressStudy.Core namespace SharpCompressStudy.Core
{ {
public static class CommonUtility public static class CommonUtility
{ {
/// <summary> /// <summary>
/// 解压文件 /// 解压文件
/// (解压到压缩文件所在目录)
/// </summary> /// </summary>
/// <param name="fileName">压缩文件包</param> /// <param name="fileName">压缩文件包</param>
/// <param name="isDelete">解压后删除压缩文件</param> /// <param name="isDelete">解压后删除压缩文件</param>
public static void Decompress(string fileName, bool isDelete) public static void Decompress(string fileName, bool isDelete)
{ {
var extName = Path.GetExtension(fileName).Trim().ToLower(); if (string.IsNullOrWhiteSpace(fileName))
switch (extName) {
{ throw new ArgumentNullException($"{fileName}");
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)
{
File.Delete(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 (!File.Exists(fileName))
if (!Directory.Exists(descDir))
{ {
Directory.CreateDirectory(descDir); throw new FileNotFoundException($"{fileName} not found");
} }
try try
{ {
using (Stream stream = File.OpenRead(fileName)) //扩展名
{ var extName = Path.GetExtension(fileName).Trim().ToLower();
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;
}
}
private static void DecompressZipFile(string fileName, bool isDelete) //文件名
{ var rarFileName = Path.GetFileName(fileName);
try
{
ExtractionOptions options = new ExtractionOptions();
//抽取顶级目录 //不带扩展名的文件名
var extractPath = Directory.GetParent(fileName)?.FullName + "22"; var rarFileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName);
if (!Directory.Exists(extractPath))
{
Directory.CreateDirectory(extractPath);
}
//解压根目录
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 && File.Exists(fileName))
if (isDelete)
{ {
File.Delete(fileName); File.Delete(fileName);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.Write($"解压报错,错误:{ex.Message}"); Console.Write($"解压报错,错误:{ex}");
throw; 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) case ".zip":
{ archive = ZipArchive.Open(compressFileName);
File.Delete(fileName); break;
}
} case ".7z":
catch (Exception ex) archive = SevenZipArchive.Open(compressFileName);
{ break;
Console.Write($"解压报错,错误:{ex}");
throw;
}
}
private static void DecompressGzFile(string fileName, bool isDelete) case ".gz":
{ archive = GZipArchive.Open(compressFileName);
try break;
{ case ".tar":
if (isDelete) archive = TarArchive.Open(compressFileName);
{ break;
File.Delete(fileName);
} default:
} throw new ArchiveException($"不支持的压缩文件格式[{compressFileName}]");
catch (Exception ex)
{
Console.Write($"解压报错,错误:{ex}");
throw;
} }
return archive;
} }
} }
} }

@ -11,6 +11,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="Resource\利港模型AB文件.rar">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resource\利港模型AB文件.zip"> <None Update="Resource\利港模型AB文件.zip">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>

@ -6,7 +6,7 @@ namespace SharpCompressStudy
public void Zip_Test() public void Zip_Test()
{ {
var file = AppDomain.CurrentDomain.BaseDirectory + "/Resource/" + "利港模型AB文件.zip"; var file = AppDomain.CurrentDomain.BaseDirectory + "/Resource/" + "利港模型AB文件.zip";
CommonUtility.Decompress(file,false); CommonUtility.Decompress(file,true);
} }
[Fact] [Fact]

@ -1,91 +0,0 @@
namespace SharpCompressStudy.Core
{
/// <summary>
/// 因为Rar压缩算法是私有的而解压文件算法是公开的。
/// 所以不能创建Rar压缩文件但能解压现有Rar文件。
/// 能解压和创建zip、tar、7z等压缩格式的文件
/// </summary>
public class WinRarFileTest:IDisposable
{
private readonly ITestOutputHelper testOutput;
public WinRarFileTest(ITestOutputHelper testOutputHelper)
{
this.testOutput = testOutputHelper;
}
/// <summary>
/// 解压Rar文件
/// 注意不能创建Rar压缩文件
/// </summary>
[Fact]
public void ExtractFromRar_Test()
{
var rarFilePath = AppDomain.CurrentDomain.BaseDirectory + "Resource\\学习2.rar";
if (!File.Exists(rarFilePath))
{
throw new FileNotFoundException("Rar文件不存在");
}
//扩展名
var extName = Path.GetExtension(rarFilePath);
//文件名
var rarFileName = Path.GetFileName(rarFilePath).Replace(extName, "");
//不带扩展名的文件名
var rarFileNameWithoutExt = Path.GetFileNameWithoutExtension(rarFilePath);
//解压根目录
var extractPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resource\\models\\temp\\", Guid.NewGuid().ToString() + "\\");
using (var archive = RarArchive.Open(rarFilePath))
{
//压缩文件是否包含同名根目录(abc.rar解决后是否有一个名为abc的根目录)
if (archive.Entries.Where(f => f.IsDirectory && f.Key == rarFileNameWithoutExt).Count() != 1)
{
extractPath = Path.Combine(extractPath, rarFileNameWithoutExt);
}
//创建解压目录
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 });
}
}
}
testOutput.WriteLine($"文件解压到目录:{extractPath}");
}
[Fact]
public void CompressToZip_Test()
{
string filesPath = AppDomain.CurrentDomain.BaseDirectory + "Resource\\学习";
var extractPathFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resource\\", Guid.NewGuid().ToString() + "\\");
var extractPathFile = Path.Combine(extractPathFolder, "学习.zip");
if (!Directory.Exists(extractPathFolder))
{
Directory.CreateDirectory(extractPathFolder);
}
using var zip = File.OpenWrite(extractPathFile);
using var zipWriter = WriterFactory.Open(zip, ArchiveType.Zip, CompressionType.Deflate);
zipWriter.WriteAll(filesPath, "*", SearchOption.AllDirectories);
}
public void Dispose()
{
GC.SuppressFinalize(this);
}
}
}
Loading…
Cancel
Save