Compactando/Descompactando Pastas e Arquivos
-
08-06-2019 - |
Pergunta
Alguém conhece uma boa maneira de compactar ou descompactar arquivos e pastas em C# rapidamente?Pode ser necessário lidar com arquivos grandes.
Nenhuma solução correta
Outras dicas
O namespace da estrutura .Net 2.0 System.IO.Compression
suporta algoritmos GZip e Deflate.Aqui estão dois métodos que compactam e descompactam um fluxo de bytes que você pode obter do seu objeto de arquivo.Você pode substituir GZipStream
para DefaultStream
nos métodos abaixo para usar esse algoritmo.Isso ainda deixa o problema de lidar com arquivos compactados com algoritmos diferentes.
public static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true);
gzip.Write(data, 0, data.Length);
gzip.Close();
return output.ToArray();
}
public static byte[] Decompress(byte[] data)
{
MemoryStream input = new MemoryStream();
input.Write(data, 0, data.Length);
input.Position = 0;
GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true);
MemoryStream output = new MemoryStream();
byte[] buff = new byte[64];
int read = -1;
read = gzip.Read(buff, 0, buff.Length);
while (read > 0)
{
output.Write(buff, 0, read);
read = gzip.Read(buff, 0, buff.Length);
}
gzip.Close();
return output.ToArray();
}
Sempre usei a Biblioteca SharpZip.
A partir do .Net 1.1, o único método disponível é acessar as bibliotecas Java.
Usando as classes Zip nas bibliotecas de classes J# para compactar arquivos e dados com C#
Não tenho certeza se isso mudou nas versões recentes.
Você pode usar um Biblioteca de terceiros, como SharpZip como Tom apontou.
Outra maneira (sem recorrer a terceiros) é usar a API do Windows Shell.Você precisará definir uma referência para a biblioteca Microsoft Shell Controls and Automation COM em seu projeto C#.Gerald Gibson tem um exemplo em:
Minha resposta seria fechar os olhos e optar por DotNetZip.Foi testado por uma grande comunidade.
GZipStream é um utilitário muito bom de usar.
Isso é muito fácil de fazer em java e, como mencionado acima, você pode acessar as bibliotecas java.util.zip em C#.Para referências consulte:
java.util.zip javadocs
Código de amostra
Usei isso há algum tempo para fazer um zip profundo (recursivo) de uma estrutura de pastas, mas acho que nunca usei a descompactação.Se eu estiver tão motivado, posso extrair esse código e editá-lo aqui mais tarde.
Outra boa alternativa também é DotNetZip.
você pode criar um arquivo zip com este método:
public async Task<string> CreateZipFile(string sourceDirectoryPath, string name)
{
var path = HostingEnvironment.MapPath(TempPath) + name;
await Task.Run(() =>
{
if (File.Exists(path)) File.Delete(path);
ZipFile.CreateFromDirectory(sourceDirectoryPath, path);
});
return path;
}
e então você pode descompactar o arquivo zip com estes métodos:
1- este método funciona com o caminho do arquivo zip
public async Task ExtractZipFile(string filePath, string destinationDirectoryName)
{
await Task.Run(() =>
{
var archive = ZipFile.Open(filePath, ZipArchiveMode.Read);
foreach (var entry in archive.Entries)
{
entry.ExtractToFile(Path.Combine(destinationDirectoryName, entry.FullName), true);
}
archive.Dispose();
});
}
2- este método funciona com fluxo de arquivo zip
public async Task ExtractZipFile(Stream zipFile, string destinationDirectoryName)
{
string filePath = HostingEnvironment.MapPath(TempPath) + Utility.GetRandomNumber(1, int.MaxValue);
using (FileStream output = new FileStream(filePath, FileMode.Create))
{
await zipFile.CopyToAsync(output);
}
await Task.Run(() => ZipFile.ExtractToDirectory(filePath, destinationDirectoryName));
await Task.Run(() => File.Delete(filePath));
}