我正在创建一个应该返回 sfx(自解压存档)的 REST 端点。就创建实际存档而言,我正在使用 Ionic.Zip 完成繁重的工作,但我在理解如何将完成的 sfx 存档写回客户端时遇到了一些麻烦。
据我所知,ZipFile.Save(Response.OutputStream)
可以很好地写回 zip 文件,令我感到惊讶的是我无法使用类似ZipFile.SaveSelfExtractor(Response.OutputStream,选项)
。根据docs ,接收流的 SaveSelfExtractor 没有重载。
我能在网上找到的例子解释了这两种情况
- 我怎么能create my own stub并先将其写回到流中,然后将 zip 存档写入同一流之上。
- 我怎么能temporarily store the sfx on the server ,然后使用 FileStream 将其写回客户端。
但我不需要也不想在服务器上临时存储 sfx 可执行文件,我也不想创建自己的 sfx stub 。我很高兴使用 Ionic 包中已经提供的 stub 。
有什么方法可以让 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();
}
}
我将此张贴给后代。这是我能想到的最好的解决方案。欢迎其他人提供更好的解决方案。
[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();
}
我是一名优秀的程序员,十分优秀!