DotNetZip: Como extrair arquivos, mas ignorando o caminho no arquivo zip?
Pergunta
Tentando extrair arquivos para uma determinada pasta ignorando o caminho no arquivo zip, mas não parece ser um caminho.
Esta parece ser uma exigência bastante básico dado todas as outras coisas boas implementado lá.
O que eu estou ausente?
código é -
using (Ionic.Zip.ZipFile zf = Ionic.Zip.ZipFile.Read(zipPath))
{
zf.ExtractAll(appPath);
}
Solução
Você precisará remover a parte do diretório do nome do arquivo pouco antes de descompactação ...
using (var zf = Ionic.Zip.ZipFile.Read(zipPath))
{
zf.ToList().ForEach(entry =>
{
entry.FileName = System.IO.Path.GetFileName(entry.FileName);
entry.Extract(appPath);
});
}
Outras dicas
Enquanto você não pode especificá-lo para uma chamada específica para Extract()
ou ExtractAll()
, a classe ZipFile
tem um campo FlattenFoldersOnExtract
. Quando definido como verdadeiro, ele achata todos os arquivos extraídos em uma pasta:
var flattenFoldersOnExtract = zip.FlattenFoldersOnExtract;
zip.FlattenFoldersOnExtract = true;
zip.ExtractAll();
zip.FlattenFoldersOnExtract = flattenFoldersOnExtract;
Isso falhará se existem 2 arquivos com nomes iguais. Por exemplo Files \ additionalfiles \ file1.txt temp \ file1.txt
arquivo Primeiro será renomeado para file1.txt no arquivo zip e quando o segundo arquivo está tentando ser renomeado uma exceção é lançada dizendo que um item com a mesma chave já existe
Você pode usar a sobrecarga que utiliza um fluxo como um parâmetro. Desta forma, você tem controle total do caminho onde os arquivos serão extraídos para.
Exemplo:
using (ZipFile zip = new ZipFile(ZipPath))
{
foreach (ZipEntry e in zip)
{
string newPath = Path.Combine(FolderToExtractTo, e.FileName);
if (e.IsDirectory)
{
Directory.CreateDirectory(newPath);
}
else
{
using (FileStream stream = new FileStream(newPath, FileMode.Create))
e.Extract(stream);
}
}
}