Как я могу перечислить содержимое папки.zip в C#?
Как я могу перечислить содержимое архива в C#? Например, как узнать, сколько элементов содержится в заархивированной папке и как они называются?
8 ответов
Наконец,.NET 4.5 или новее имеет встроенную возможность обрабатывать общие zip-файлы с помощью System.IO.Compression.ZipArchive
класс ( http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive%28v=vs.110%29.aspx) в сборке System.IO.Compression. Нет необходимости в какой-либо сторонней библиотеке.
string zipPath = @"c:\example\start.zip";
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
Console.WriteLine(entry.FullName);
}
}
DotNetZip - манипулирование Zip-файлами на языках.NET
DotNetZip - это небольшая, простая в использовании библиотека классов для работы с файлами.zip. Он позволяет приложениям.NET, написанным на VB.NET, C#, любом языке.NET, легко создавать, читать и обновлять zip-файлы.
Пример кода для чтения почтового индекса:
using (var zip = ZipFile.Read(PathToZipFolder))
{
int totalEntries = zip.Entries.Count;
foreach (ZipEntry e in zip.Entries)
{
e.FileName ...
e.CompressedSize ...
e.LastModified...
}
}
Если вы используете.Net Framework 3.0 или более позднюю версию, проверьте пространство имен System.IO.Packaging. Это снимет вашу зависимость от внешней библиотеки.
В частности, проверьте класс ZipPackage.
Проверьте в SharpZipLib
ZipInputStream inStream = new ZipInputStream(File.OpenRead(fileName));
while (inStream.GetNextEntry())
{
ZipEntry entry = inStream.GetNextEntry();
//write out your entry's filename
}
Черт, этот код, использующий среду выполнения J#, отвратителен! И я не согласен с тем, что это лучший способ - J# больше не поддерживается. И это ОГРОМНОЕ время выполнения, если вам нужна только поддержка ZIP.
Как насчет этого - он использует DotNetZip (бесплатная лицензия MS-Public)
using (ZipFile zip = ZipFile.Read(zipfile) )
{
bool header = true;
foreach (ZipEntry e in zip)
{
if (header)
{
System.Console.WriteLine("Zipfile: {0}", zip.Name);
if ((zip.Comment != null) && (zip.Comment != ""))
System.Console.WriteLine("Comment: {0}", zip.Comment);
System.Console.WriteLine("\n{1,-22} {2,9} {3,5} {4,9} {5,3} {6,8} {0}",
"Filename", "Modified", "Size", "Ratio", "Packed", "pw?", "CRC");
System.Console.WriteLine(new System.String('-', 80));
header = false;
}
System.Console.WriteLine("{1,-22} {2,9} {3,5:F0}% {4,9} {5,3} {6:X8} {0}",
e.FileName,
e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
e.UncompressedSize,
e.CompressionRatio,
e.CompressedSize,
(e.UsesEncryption) ? "Y" : "N",
e.Crc32);
if ((e.Comment != null) && (e.Comment != ""))
System.Console.WriteLine(" Comment: {0}", e.Comment);
}
}
Я здесь относительно новичок, поэтому, может быть, я не понимаю, что происходит.:-) В настоящее время в этой теме есть 4 ответа, где два лучших ответа были отклонены. (Pearcewg's и cxfx's) Статья, на которую указывает Pearcewg, важна, потому что она проясняет некоторые вопросы лицензирования с SharpZipLib. Недавно мы оценили несколько библиотек сжатия.Net и обнаружили, что DotNetZip в настоящее время является лучшей альтернативой.
Очень краткое резюме:
System.IO.Packaging значительно медленнее, чем DotNetZip.
SharpZipLib - это GPL - см. Статью.
Поэтому для начала я проголосовал за эти два ответа.
Ким.
Если вы похожи на меня и не хотите использовать внешний компонент, вот код, который я разработал вчера вечером с использованием класса.NET ZipPackage.
var zipFilePath = "c:\\myfile.zip";
var tempFolderPath = "c:\\unzipped";
using (Package package = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read))
{
foreach (PackagePart part in package.GetParts())
{
var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/')));
var targetDir = target.Remove(target.LastIndexOf('\\'));
if (!Directory.Exists(targetDir))
Directory.CreateDirectory(targetDir);
using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read))
{
source.CopyTo(File.OpenWrite(target));
}
}
}
Что следует отметить:
ZIP-архив ДОЛЖЕН иметь в своем корневом каталоге файл [Content_Types].xml. Это не было проблемой для моих требований, так как я буду контролировать архивирование любых ZIP-файлов, которые извлекаются с помощью этого кода. Для получения дополнительной информации о файле [Content_Types].xml, пожалуйста, обратитесь к: Новый стандарт для упаковки ваших данных Ниже приведен пример файла ниже на рисунке 13 статьи.
Этот код использует метод Stream.CopyTo в.NET 4.0
Наилучшим способом является использование встроенной в.NET функции J# zip, как показано в MSDN: http://msdn.microsoft.com/en-us/magazine/cc164129.aspx. В этой ссылке приведен полный рабочий пример чтения и записи приложения в zip-файлы. Для конкретного примера перечисления содержимого zip-файла (в данном случае пакета приложения Silverlight .xap) код может выглядеть следующим образом:
ZipFile package = new ZipFile(packagePath);
java.util.Enumeration entries = package.entries();
//We have to use Java enumerators because we
//use java.util.zip for reading the .zip files
while ( entries.hasMoreElements() )
{
ZipEntry entry = (ZipEntry) entries.nextElement();
if (!entry.isDirectory())
{
string name = entry.getName();
Console.WriteLine("File: " + name + ", size: " + entry.getSize() + ", compressed size: " + entry.getCompressedSize());
}
else
{
// Handle directories...
}
}
У Айдсмана был правильный указатель, но есть проблемы. В частности, могут возникнуть проблемы с открытием zip-файлов, но это допустимое решение, если вы собираетесь создавать только пакеты. ZipPackage реализует абстрактный класс Package и позволяет манипулировать zip-файлами. Вот пример того, как это сделать в MSDN: http://msdn.microsoft.com/en-us/library/ms771414.aspx. Примерно код будет выглядеть так:
string packageRelationshipType = @"http://schemas.microsoft.com/opc/2006/sample/document";
string resourceRelationshipType = @"http://schemas.microsoft.com/opc/2006/sample/required-resource";
// Open the Package.
// ('using' statement insures that 'package' is
// closed and disposed when it goes out of scope.)
foreach (string packagePath in downloadedFiles)
{
Logger.Warning("Analyzing " + packagePath);
using (Package package = Package.Open(packagePath, FileMode.Open, FileAccess.Read))
{
Logger.OutPut("package opened");
PackagePart documentPart = null;
PackagePart resourcePart = null;
// Get the Package Relationships and look for
// the Document part based on the RelationshipType
Uri uriDocumentTarget = null;
foreach (PackageRelationship relationship in
package.GetRelationshipsByType(packageRelationshipType))
{
// Resolve the Relationship Target Uri
// so the Document Part can be retrieved.
uriDocumentTarget = PackUriHelper.ResolvePartUri(
new Uri("/", UriKind.Relative), relationship.TargetUri);
// Open the Document Part, write the contents to a file.
documentPart = package.GetPart(uriDocumentTarget);
//ExtractPart(documentPart, targetDirectory);
string stringPart = documentPart.Uri.ToString().TrimStart('/');
Logger.OutPut(" Got: " + stringPart);
}
// Get the Document part's Relationships,
// and look for required resources.
Uri uriResourceTarget = null;
foreach (PackageRelationship relationship in
documentPart.GetRelationshipsByType(
resourceRelationshipType))
{
// Resolve the Relationship Target Uri
// so the Resource Part can be retrieved.
uriResourceTarget = PackUriHelper.ResolvePartUri(
documentPart.Uri, relationship.TargetUri);
// Open the Resource Part and write the contents to a file.
resourcePart = package.GetPart(uriResourceTarget);
//ExtractPart(resourcePart, targetDirectory);
string stringPart = resourcePart.Uri.ToString().TrimStart('/');
Logger.OutPut(" Got: " + stringPart);
}
}
}
Лучше всего использовать J#, как показано в MSDN: http://msdn.microsoft.com/en-us/magazine/cc164129.aspx
В этой статье есть ссылки на большее количество библиотек C# .zip с разными лицензиями, таких как SharpNetZip и DotNetZip: как читать файлы из несжатого zip в C#?, Они могут быть неподходящими из-за лицензионных требований.