【问题标题】:ZipArchive returning empty files c#ZipArchive返回空文件c#
【发布时间】:2015-11-13 08:03:41
【问题描述】:

所以我已经实现了压缩文件,但现在我遇到了另一个问题,即 zip 文件夹包含空文件。压缩后的文件大小为0字节。

这就是我压缩文件的方式

try
{
    var outPutDirectory = AppDomain.CurrentDomain.BaseDirectory;
    string logoimage = Path.Combine(outPutDirectory, "images\\error.png");

    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.BufferOutput = false;
    HttpContext.Current.Response.ContentType = "application/zip";
    HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=pauls_chapel_audio.zip");

    using (MemoryStream ms = new MemoryStream())
    {
        // create new ZIP archive within prepared MemoryStream
        using (ZipArchive zip = new ZipArchive(ms, ZipArchiveMode.Create, true))
        {
            var demoFile = zip.CreateEntry(logoimage);
            // add some files to ZIP archive
        }
        ms.WriteTo(HttpContext.Current.Response.OutputStream);
    }

    return true;
}

另一个问题是压缩文件夹与图像的路径相同。所以就像

ZippFolder/A/B/C/image...

我只需要

ZipFolder/content

【问题讨论】:

  • 嗯 2 件事 1. 您的代码似乎是 asp.net 而不是 c# 特定的? 2.你正在制作一个很好的记忆流,但它从来没有“准备好”,也就是设置为任何内容?
  • 不知道怎么写。我是这方面的新手,你能举个例子吗?
  • HttpContext 听起来像是来自 asp.net 的东西,因此您应该将该标签添加到您的问题中。至于 memoryStream 你做 new MemoryStream() 但只创建一个空的内存流。您没有设置源的来源(因为我不知道有关您的项目的更多详细信息,所以我不能说您应该如何设置/初始化它)。您应该添加数据应该来自哪里。如果是来自文件下载/上传对话框,...
  • 暂时来自静态文件。
  • 但整个事情应该是一个网络应用程序?

标签: c# asp.net compression


【解决方案1】:
var demoFile = zip.CreateEntry(logoimage);

这会在 ZIP 文件中创建一个名为 logoimage 的条目(即 /A/B/C/images/error.png 或任何完整路径)。

但是你从来没有写过那个条目,所以它是空的。此外,如果您想使用不同的路径,则应在此处指定:

var demoFile = zip.CreateEntry("content\\error.png");
using (StreamWriter writer = new StreamWriter(demoFile.Open()))
using (StreamReader reader = new StreamReader(logoimage))
{
    writer.Write(reader.ReadToEnd());
}

或者,您也可以完全跳过StreamWriter,直接写入流:

using (Stream stream = demoFile.Open())
using (StreamReader reader = new StreamReader(logoimage))
{
    reader.BaseStream.CopyTo(stream);
}

顺便说一句。您可以跳过外部的MemoryStream,首先要在其中写入压缩文件,然后将该流写入OutputStream。相反,您可以直接写入该流。只需将其传递给ZipFile 构造函数即可:

Stream output = HttpContext.Current.Response.OutputStream;
using (ZipArchive zip = new ZipArchive(output, ZipArchiveMode.Create, true))
{
    …
}

【讨论】:

  • 他不能只是 .CopyTo HttpContext.Current.Response.OutputStream 吗?而不是 writer,因为那是他无论如何都想放置数据的地方
  • 问题是没有把输出放到输出流中。问题是他想从 HTTP 请求中返回一个压缩文件,但他从未将实际内容添加到 zip 中。
  • 我在尝试 CopyTo() 时收到此错误“System.IO.StreamReader”不包含“CopyTo”的定义,并且没有扩展方法“CopyTo”接受“System”类型的第一个参数.IO.StreamReader' 可以找到(您是否缺少 using 指令或程序集引用?)'
  • @poke yepp 我知道他从来没有读过任何东西。我的帖子的意思是,最后他想创建 zip 是的,但他也想把它作为 http 输出(因为整个事情应该是下载)。然后他是否需要在流读取器中再次读取 demoFile 并将其写入输出,或者那里有更快的方法?
  • @ChaudhryMohsinAli 是的,抱歉,搞混了。 CopyTo 仅适用于流,不适用于 StreamReaders/Writers
猜你喜欢
  • 2018-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2015-06-07
  • 2019-07-29
  • 2019-10-12
相关资源
最近更新 更多