DotNetZip将自提取器直接保存到Response.OutputStream

时间:2016-04-13 10:47:30

标签: c# dotnetzip

我正在创建一个REST端点,它应该返回一个sfx(Self Extracting Archive)。就创建实际存档而言,我正在使用Ionic.Zip进行繁重的工作,但是我在理解如何将完成的sfx存档写回客户端时遇到了一些麻烦。

据我所知,ZipFile.Save(Response.OutputStream)可以正常编写一个zip文件,我很惊讶我不能用ZipFile.SaveSelfExtractor(Response.OutputStream, options)之类的东西做同样的事情。根据{{​​3}},SaveSelfExtractor没有超载,它接收流。

我能够在网上挖掘的例子解释了

  1. 我怎样才能docs并首先将其写回流中,然后将zip存档写在同一个流的顶部。
  2. 我如何create my own stub,然后使用FileStream将其写回客户端。
  3. 但我不需要也不想在服务器上临时存储sfx可执行文件,我也不想创建自己的sfx存根。我很高兴使用Ionic包中已经提供的存根。

    我有没有办法让Ionic.Zip.ZipFile创建sfx并一次性将其写回Response.OutputStream

    这就是我现在所拥有的:

    using System.IO;
    using Ionic.Zip;
    using System.Web.Http;
    using Context = System.Web.HttpContext;
    
    namespace MyCompany.web.Controllers
    {
        [HttpGet]
        public void Export()
        {
            var response = Context.Current.Response;
            var stream = response.OutputStream;
    
            // Create the zip archive in memory
            using (var archive = new ZipFile())
            {
                archive.Comment = "Self extracting export";
                archive.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
    
                using (var memoryStream = new MemoryStream())
                using (var streamWriter = new StreamWriter(memoryStream))
                {
                    streamWriter.WriteLine("Hello World");
                    archive.AddEntry("testfile.txt", memoryStream.ToArray());
                }
    
                // What I want is to write this to outputstream
                archive.SaveSelfExtractor(/*stream*/ "export.exe", new SelfExtractorSaveOptions
                {
                    Flavor = SelfExtractorFlavor.ConsoleApplication,
                    Quiet = true,
                    ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently,
                    RemoveUnpackedFilesAfterExecute = false
                });
                /*archive.Save(stream); // This will write to outputstream */
            }
    
            response.AddHeader("Content-Disposition", "attachment; filename=export.exe");
            response.AddHeader("Content-Description", "File Transfer");
            response.AddHeader("Content-Transfer-Encoding", "binary");
            response.ContentType = "application/exe";
    
            response.Flush();
            response.Close();
            response.End();
        }
    }
    

2 个答案:

答案 0 :(得分:0)

我发布此内容给后人。这是我能想到的最好的解决方案。欢迎其他人提供更好的解决方案。

    [HttpGet]
    public void Export()
    {
        var response = Context.Current.Response;
        var writeStream = response.OutputStream;

        var name      = "export.exe";

        // Create the zip archive in memory
        using (var archive = new Ionic.Zip.ZipFile())
        {
            archive.Comment = "Self extracting export";
            archive.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;

            using (var memoryStream = new MemoryStream())
            using (var streamWriter = new StreamWriter(memoryStream))
            {
                streamWriter.WriteLine("Hello World");
                streamWriter.Flush();
                archive.AddEntry("testfile.txt", memoryStream.ToArray());
            }

            // Write sfx file to temp folder on server
            archive.SaveSelfExtractor(name, new Ionic.Zip.SelfExtractorSaveOptions
            {
                Flavor = Ionic.Zip.SelfExtractorFlavor.ConsoleApplication,
                Quiet = true,
                DefaultExtractDirectory = "\\temp",
                SfxExeWindowTitle = "Export",
                ExtractExistingFile = Ionic.Zip.ExtractExistingFileAction.OverwriteSilently,
                RemoveUnpackedFilesAfterExecute = false
            });

            // Read file back and output to response
            using (var fileStream = new FileStream(name, FileMode.Open))
            {
                byte[] buffer = new byte[4000];
                int n = 1;
                while (n != 0)
                {
                    n = fileStream.Read(buffer, 0, buffer.Length);
                    if (n != 0)
                        writeStream.Write(buffer, 0, n);
                }
            }

            // Delete the temporary file
            if (File.Exists(name))
            {
                try { File.Delete(name); }
                catch (System.IO.IOException exc1)
                {
                    Debug.WriteLine("Warning: Could not delete file: {0} {1}", name, exc1);
                }
            }
        }

        response.AddHeader("Content-Disposition", "attachment; filename=" + name);
        response.AddHeader("Content-Description", "File Transfer");
        response.AddHeader("Content-Transfer-Encoding", "binary");
        response.ContentType = "application/exe";

        response.Flush();
        response.Close();
        response.End();
    }

答案 1 :(得分:-1)

using (ZipFile zip = new ZipFile())
{
    //string DirPath = Application.StartupPath + @"\CSVfile\files" + DateTime.Now.ToString("yyMMdd");
    string DirPath = Server.MapPath("DoneCSV//" + ViewState["Filepath"]);
    string savepath = DirPath + "/" + ViewState["Filepath"] + "_" + DateTime.Now.ToString("yyMMdd") + ".zip";
    zip.AddDirectory(DirPath);
    zip.Save(savepath);
    //sendmail(savepath);
}