【问题标题】:How to work with a ZipArchive in C#如何在 C# 中使用 ZipArchive
【发布时间】:2014-12-02 17:07:54
【问题描述】:

我有一个 ZipArchive,并希望访问其中的一个文件。我不知道该怎么做,但我有一个清单

List<ZipContents> importList = new List<ZipContents>();

其中有两个参数:

  1. ZipArchive 称为 ZipFile
  2. String 称为 FileName

ZipArchiveimportList.ZipFile 中,我需要找到一个与Zip 文件名同名的XML 文件。

目前我有这个:

foreach (var import in importList)
{
    var fn = import.FileName; // This is the actual file name of the zip file 
    // that was added into the ZipArchive. 
    // I will need to access the specific XML file need in the Zip by associating with
    // fn

    // ToDo: Extract XML file needed 
    // ToDo: Begin to access its contents...

}

例如,代码正在查找名称为 test.zip 的 ZipArchive。将有一个名为 test.xml 的文件,然后我需要能够访问其内容。

就像我上面所说的,我需要能够访问该文件的内容。很抱歉,我没有支持如何执行此操作的代码,但我找不到其他任何东西...

我已经浏览了很多 ZIpArchive 文档(包括:http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive%28v=vs.110%29.aspx)和其他关于如何执行此操作的帖子,但我发现都是空的。有人知道如何做到这一点吗?任何帮助将非常感激。谢谢!

【问题讨论】:

  • 我希望我至少能够使用import.ZipFile.Entries["test.xml"] 通过文件名访问它,但我什至无法达到目标...
  • 是单个xml条目还是可以有多个xml条目?
  • 如果是单个 xml 条目,只需获取您的存档名称,然后对其执行 string.replace,将 .zip 替换为 .xml,然后按正常方式提取...
  • 使用 (MemoryStream ms = new MemoryStream()) { using (ZipFile zip = ZipFile.Read(docloc)) { zip.Encryption = EncryptionAlgorithm.WinZipAes256; //如果存档被加密。 zip.Password = somePassword; //如果这是一个密码存档.. ZipEntry entry = zip(docloc.Replace(".zip",".xml"); entry.Extract(ms); } b = ms.ToArray; } 我把它插入了一个代码转换器,所以它可能需要一些细微的调整,但据我所知,它似乎是正确的。对于格式设置抱歉,在评论中效果不佳。

标签: c# ziparchive


【解决方案1】:

您需要将存档解压缩到一个目录(也可以使用 temp,因为我假设您不想保留这些):

archive.ExtractToDirectory("path string");

//Get the directory info for the directory you just extracted to
DirectoryInfo di = new DirectoryInfo("path string");

//find the xml file you want
FileInfo fi = di.GetFiles(string.Format("{0}.xml", archiveName)).FirstOrDefault();

//if the file was found, do your thing
if(fi != null)
{
    //Do your file stuff here.
}

//delete the extracted directory
di.Delete();

编辑:只需解压您关心的文件即可:

//find your file
ZipArchiveEntry entry = archive
                         .Entries
                         .FirstOrDefault(e => 
                             e.Name == string.Format("{0}.xml", archiveName));

if(entry != null)
{
   //unpack your file
   entry.ExtractToFile("path to extract to");

   //do your file stuff here
}

//delete file if you want

【讨论】:

  • 感谢发帖!在archive.ExtractToDirectory("path string"); 中究竟是什么archive。那会是我的import.ZipFile吗?
  • 那将是你的 ZipArchive 对象
  • 如果您不想解压整个文件,您实际上也可以解压单个文件,但它涉及更多一点。
  • 除了di.Delete(); 之外,一切似乎都井井有条,我不断收到错误消息说目录不为空。有没有办法删除目录?
  • 改用di.Delete(true);
【解决方案2】:

您链接的 MSDN 很好地解释了如何访问这些文件。在这里它适用于您的示例。

// iterate over the list items
foreach (var import in importList)
{
    var fn = import.FileName;

    // iterate over the actual archives
    foreach (ZipArchiveEntry entry in import.ZipFile.Entries)
    {
        // only grab files that end in .xml
        if (entry.FullName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
        {
            // this extracts the file
            entry.ExtractToFile(Path.Combine(@"C:\extract", entry.FullName));

            // this opens the file as a stream
            using(var stream = new StreamReader(entry.Open())){
                // this opens file as xml stream
                using(var xml = XmlReader.Create(stream){
                    // do some xml access on an arbitrary node
                    xml.MoveToContent();
                    xml.ReadToDescendant("my-node");
                    var item = xml.ReadElementContentAsString();
                }
            }
        }
    }
}

【讨论】:

    【解决方案3】:

    以下将提取一个名为file.xmlxml 文件并将其读取到XDocument 对象:

    var xmlEntry = importList.SelectMany(y => y.Entries)
                             .FirstOrDefault(entry => entry.Name.Equals("file.xml",
                                                      StringComparison.OrdinalIgnoreCase));
    if (xmlEntry == null)
    {
        return;
    }
    
    // Open a stream to the underlying ZipArchiveEntry
    using (XDocument xml = XDocument.Load(xmlEntry.Open()))
    {
        // Do stuff with XML
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 2013-02-14
      • 1970-01-01
      • 2011-05-16
      相关资源
      最近更新 更多