简体   繁体   English

从包含 zip 的流中提取文件

[英]Extract files from stream containing zip

I am making a GET request using HttpClient to download a zip file from the internet.我正在使用 HttpClient 发出 GET 请求以从 Internet 下载 zip 文件。 I want to extract all the files contained in the zip file without saving the zip file to disk.我想提取 zip 文件中包含的所有文件,而不将 zip 文件保存到磁盘。 Currently, I am able to download and save the zip file to disk, extract its contents and then delete the zip file from disk.目前,我可以下载 zip 文件并将其保存到磁盘,提取其内容,然后从磁盘中删除 zip 文件。 This perfectly fine.这完全没问题。 However, I want to optimize the process.但是,我想优化该过程。 I found a way to extract the contents directly from the downloaded zip stream but I have to specify the filenames and extensions.我找到了一种直接从下载的 zip 流中提取内容的方法,但我必须指定文件名和扩展名。 I am not sure how to extract the contents while preserving their original filenames and extensions without me specifying them.我不确定如何在不指定的情况下在保留原始文件名和扩展名的同时提取内容。

Current Approach:当前方法:

string requestUri = "https://www.nuget.org/api/v2/package/" + PackageName + "/" + PackageVersion;
HttpResponseMessage response = await client.GetAsync(requestUri);
response.EnsureSuccessStatusCode();
using Stream PackageStream = await response.Content.ReadAsStreamAsync();
SaveStream($"{DownloadPath}.zip", PackageStream);
ZipFile.ExtractToDirectory($"{DownloadPath}.zip", ExtractPath);
File.Delete($"{DownloadPath}.zip");

// Directly extract Zip contents without saving file and without losing filename and extension
using (ZipArchive archive = new ZipArchive(await response.Content.ReadAsStreamAsync()))
{
   foreach (ZipArchiveEntry entry in archive.Entries)
   {
       using (Stream stream = entry.Open())
       {
           using (FileStream file = new FileStream("file.txt", FileMode.Create, FileAccess.Write))
           {
               stream.CopyTo(file);
           }
       }
   }
}

.NET 4.8 .NET 4.8
.NET Core 3.1 .NET 核心 3.1
C# 8.0 C# 8.0

Any help in this regards would be appreciated.在这方面的任何帮助将不胜感激。
Please feel free to comment on alternative approaches or suggestions.请随时对替代方法或建议发表评论。
Thank you in advance.先感谢您。

ZipArchiveEntry has a Name and FullName property that can be used to get the names of the files within the archive while preserving their original filenames and extensions ZipArchiveEntry具有NameFullName属性,可用于获取存档中文件的名称,同时保留其原始文件名和扩展名

The FullName property contains the relative path, including the subdirectory hierarchy, of an entry in a zip archive. FullName 属性包含 zip 存档中条目的相对路径,包括子目录层次结构。 (In contrast, the Name property contains only the name of the entry and does not include the subdirectory hierarchy.) (相反,Name 属性仅包含条目的名称,不包含子目录层次结构。)

For example例如

using (ZipArchive archive = new ZipArchive(await response.Content.ReadAsStreamAsync())) {
    foreach (ZipArchiveEntry entry in archive.Entries) {
        using (Stream stream = entry.Open()) {                        
            string destination = Path.GetFullPath(Path.Combine(downloadPath, entry.FullName));

            var directory = Path.GetDirectoryName(destination);
            if (!Directory.Exists(directory))
                Directory.CreateDirectory(directory);

            using (FileStream file = new FileStream(destination, FileMode.Create, FileAccess.Write)) {
                await stream.CopyToAsync(file);
            }
        }
    }
}

will extract the files in the same subdirectory hierarchy as they were stored in the archive while if entry.Name was used, all the files would be extracted to the same location.将在与存档中存储的相同子目录层次结构中提取文件,而如果使用entry.Name ,所有文件将被提取到同一位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM