如何在 c# 中列出 .zip 文件夹的内容?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/307774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I list the contents of a .zip folder in c#?
提问by vbroto
How can I list the contents of a zipped folder in C#? For example how to know how many items are contained within a zipped folder, and what is their name?
如何在 C# 中列出压缩文件夹的内容?例如,如何知道一个压缩文件夹中包含多少个项目,它们的名称是什么?
回答by Chris Ballance
Check into SharpZipLib
ZipInputStream inStream = new ZipInputStream(File.OpenRead(fileName));
while (inStream.GetNextEntry())
{
ZipEntry entry = inStream.GetNextEntry();
//write out your entry's filename
}
回答by Chris Fulstow
DotNetZip- Zip file manipulation in .NET languages
DotNetZip- .NET 语言中的 Zip 文件操作
DotNetZip is a small, easy-to-use class library for manipulating .zip files. It can enable .NET applications written in VB.NET, C#, any .NET language, to easily create, read, and update zip files.
DotNetZip 是一个小型、易于使用的类库,用于操作 .zip 文件。它可以使用 VB.NET、C#、任何 .NET 语言编写的 .NET 应用程序轻松创建、读取和更新 zip 文件。
sample code to read a zip:
读取 zip 的示例代码:
using (var zip = ZipFile.Read(PathToZipFolder))
{
int totalEntries = zip.Entries.Count;
foreach (ZipEntry e in zip.Entries)
{
e.FileName ...
e.CompressedSize ...
e.LastModified...
}
}
回答by Adrian Clark
If you are using .Net Framework 3.0 or later, check out the System.IO.Packaging Namespace. This will remove your dependancy on an external library.
如果您使用 .Net Framework 3.0 或更高版本,请查看System.IO.Packaging Namespace。这将消除您对外部库的依赖。
Specifically check out the ZipPackage Class.
具体查看ZipPackage Class。
回答by Kim Major
I'm relatively new here so maybe I'm not understanding what's going on. :-) There are currently 4 answers on this thread where the two best answers have been voted down. (Pearcewg's and cxfx's) The article pointed to by pearcewg is important because it clarifies some licensing issues with SharpZipLib. We recently evaluated several .Net compression libraries, and found that DotNetZip is currently the best aleternative.
我在这里相对较新,所以也许我不明白发生了什么。:-) 此线程上目前有 4 个答案,其中两个最佳答案已被否决。(Pearcewg 的和 cxfx 的)pearcewg 指出的文章很重要,因为它阐明了 SharpZipLib 的一些许可问题。我们最近评估了几个 .Net 压缩库,发现 DotNetZip 是目前最好的替代方案。
Very short summary:
非常简短的总结:
System.IO.Packaging is significantly slower than DotNetZip.
SharpZipLib is GPL - see article.
System.IO.Packaging 比 DotNetZip 慢得多。
SharpZipLib 是 GPL - 请参阅文章。
So for starters, I voted those two answers up.
所以对于初学者来说,我对这两个答案投了赞成票。
Kim.
金。
回答by vbroto
The best way is to use the .NET built in J# zip functionality, as shown in MSDN: http://msdn.microsoft.com/en-us/magazine/cc164129.aspx. In this link there is a complete working example of an application reading and writing to zip files. For the concrete example of listing the contents of a zip file (in this case a Silverlight .xap application package), the code could look like this:
最好的方法是使用 .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...
}
}
Aydsman had a right pointer, but there are problems. Specifically, you might find issues opening zip files, but is a valid solution if you intend to onlycreate pacakges. ZipPackage implements the abstract Package class and allows manipulation of zip files. There is a sample of how to do it in MSDN: http://msdn.microsoft.com/en-us/library/ms771414.aspx. Roughly the code would look like this:
Aydsman 有一个正确的指针,但存在问题。具体来说,您可能会发现打开 zip 文件的问题,但如果您只想创建 pacakges ,这是一个有效的解决方案。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);
}
}
}
The best way seems to use J#, as shown in MSDN: http://msdn.microsoft.com/en-us/magazine/cc164129.aspx
最好的方法似乎是使用 J#,如 MSDN 所示:http: //msdn.microsoft.com/en-us/magazine/cc164129.aspx
There are pointers to more c# .zip libraries with different licenses, like SharpNetZip and DotNetZip in this article: how to read files from uncompressed zip in c#?. They might be unsuitable because of the license requirements.
有指向更多具有不同许可证的 c# .zip 库的指针,例如本文中的 SharpNetZip 和 DotNetZip:如何在 c# 中从未压缩的 zip 中读取文件?. 由于许可证要求,它们可能不合适。
回答by Cheeso
Ick - that code using the J# runtime is hideous! And I don't agree that it is the best way - J# is out of support now. And it is a HUGE runtime, if all you want is ZIP support.
Ick - 使用 J# 运行时的代码太可怕了!而且我不同意这是最好的方法 - J# 现在不支持了。它是一个巨大的运行时,如果你想要的只是 ZIP 支持。
How about this - it uses DotNetZip(Free, MS-Public license)
怎么样 - 它使用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);
}
}
回答by Joshua
If you are like me and do not want to use an external component, here is some code I developed last night using .NET's ZipPackage class.
如果您像我一样不想使用外部组件,这里是我昨晚使用 .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));
}
}
}
Things to note:
注意事项:
The ZIP archive MUST have a [Content_Types].xml file in its root. This was a non-issue for my requirements as I will control the zipping of any ZIP files that get extracted through this code. For more information on the [Content_Types].xml file, please refer to: A New Standard For Packaging Your DataThere is an example file below Figure 13 of the article.
This code uses the Stream.CopyTo method in .NET 4.0
ZIP 存档必须在其根目录中有一个 [Content_Types].xml 文件。这对我的要求来说不是问题,因为我将控制通过此代码提取的任何 ZIP 文件的压缩。有关 [Content_Types].xml 文件的更多信息,请参阅:用于打包数据的新标准文章图 13 下方有一个示例文件。
此代码使用 .NET 4.0 中的 Stream.CopyTo 方法
回答by Csaba Toth
.NET 4.5 or newer finally has built-in capability to handle generic zip files with the System.IO.Compression.ZipArchive
class (http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive%28v=vs.110%29.aspx) in assembly System.IO.Compression. No need for any 3rd party library.
.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 中。不需要任何 3rd 方库。
string zipPath = @"c:\example\start.zip";
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
Console.WriteLine(entry.FullName);
}
}