如何将文件解压缩到.NET内存流?

Pur*_*ome 30 .net c# ftp

我有文件(来自第三方)正在FTP到我们服务器上的目录.我下载它们并处理它们甚至'x'分钟.效果很好.

现在,一些文件是.zip文件.这意味着我无法处理它们.我需要先解压缩它们.

FTP没有zip/unzipping的概念 - 所以我需要抓取zip文件,解压缩然后处理它.

看看MSDN zip api,我似乎无法解压缩到内存流?

所以这是唯一的方法......

  1. 解压缩到一个文件(什么目录?需要一些非常临时的位置...)
  2. 阅读文件内容
  3. 删除文件.

注意:文件的内容很小 - 比如4k < - > 1000k.

Mar*_*ell 64

Zip压缩支持内置于:

using System.IO;
using System.IO.Compression;
// ^^^ requires a reference to System.IO.Compression.dll
static class Program
{
    const string path = ...
    static void Main()
    {
        using(var file = File.OpenRead(path))
        using(var zip = new ZipArchive(file, ZipArchiveMode.Read))
        {
            foreach(var entry in zip.Entries)
            {
                using(var stream = entry.Open())
                {
                    // do whatever we want with stream
                    // ...
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

通常情况下,你应该避免它复制到另一个流-只是用它"现况",但是,如果你绝对需要它MemoryStream,你可以这样做:

using(var ms = new MemoryStream())
{
    stream.CopyTo(ms);
    ms.Position = 0; // rewind
    // do something with ms
}
Run Code Online (Sandbox Code Playgroud)

  • @Uriil也,`ZipFile`需要一个额外的程序集引用(System.IO.Compression.FileSystem.dll),只是为了避免一个简单的`File.OpenRead` - 似乎不值得 (4认同)
  • @Uriil好,首先我不确定为什么这个类甚至存在:`ZipFile`上的所有方法实际上都是关于`ZipArchive`类 - 对我来说,它们都应该是`ZipArchive`上的静态成员!但更具体地说,因为OP正在谈论从现有来源获取数据 - 在这种情况下是FTP.在这种情况下,您不能保证您有*文件*,但通常可以假设您有*流*.因此,显示如何从流*中执行*更具可重用性并适用于任何上下文,而不仅仅是文件.但可以肯定:你可以在这里使用`ZipFile.OpenRead`. (3认同)
  • @linquize 作为专业人士,我们最好自己**不支持 XP**:这样做会使我们的客户/客户面临风险(通过提供隐式批准)。该操作系统已正式死亡。最后一个 EOL 日期大约是 2 周后。“2014 年 4 月 8 日之后,Windows XP 的支持和安全更新将不再可用。” (2认同)
  • @JasonBaley 以要求我们先发制人地将所有内容压缩到内存中为代价;利弊 (2认同)

dca*_*tro 9

您可以使用ZipArchiveEntry.Open获取流.

此代码假定zip存档有一个文本文件.

using (FileStream fs = new FileStream(path, FileMode.Open))
using (ZipArchive zip = new ZipArchive(fs) )
{
    var entry = zip.Entries.First();

    using (StreamReader sr = new StreamReader(entry.Open()))
    {
        Console.WriteLine(sr.ReadToEnd());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 显而易见的评论:如果数据不是文本,或者如果数据处于不寻常的编码但缺少BOM,这将以令人讨厌的方式破坏 (3认同)
  • @Gusdor 更容易阅读,更容易理解 (IMO),并防止代码向右爆炸。代码可读性是一个特性。 (2认同)

小智 7

using (ZipArchive archive = new ZipArchive(webResponse.GetResponseStream()))
{
     foreach (ZipArchiveEntry entry in archive.Entries)
     {
        Stream s = entry.Open();
        var sr = new StreamReader(s);
        var myStr = sr.ReadToEnd();
     }
} 
Run Code Online (Sandbox Code Playgroud)


Uri*_*iil 5

看起来像这里是你需要的:

using (var za = ZipFile.OpenRead(path))
{
    foreach (var entry in sa.Entries)
    {
        using (var r = new StreamReader(entry.Open()))
        {
            //your code here
        }
    }
}
Run Code Online (Sandbox Code Playgroud)