DotNetZip 将自解压器直接保存到 Response.OutputStream
DotNetZip save self-extractor directly to Response.OutputStream
我正在创建一个 REST 端点,它应该 return 一个 sfx(自解压存档)。我正在使用 Ionic.Zip 来完成创建实际存档的繁重工作,但我在理解如何将完成的 sfx 存档写回客户端时遇到了一些麻烦。
据我所知,ZipFile.Save(Response.OutputStream)
可以很好地写回 zip 文件,我很惊讶我不能使用 ZipFile.SaveSelfExtractor(Response.OutputStream, options)
之类的东西来做同样的事情。根据 docs,接收流的 SaveSelfExtractor 没有重载。
我可以在网上找到的例子解释了
- 我如何才能 create my own stub 并先将其写回到流中,然后将 zip 存档写入同一流之上。
- 如何temporarily store the sfx on the server,然后使用 FileStream 将其写回客户端。
但我不需要也不想在服务器上临时存储 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();
}
}
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);
}
我将此张贴给后代。这是我能想到的最好的解决方案。欢迎其他人提供更好的解决方案。
[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();
}
我正在创建一个 REST 端点,它应该 return 一个 sfx(自解压存档)。我正在使用 Ionic.Zip 来完成创建实际存档的繁重工作,但我在理解如何将完成的 sfx 存档写回客户端时遇到了一些麻烦。
据我所知,ZipFile.Save(Response.OutputStream)
可以很好地写回 zip 文件,我很惊讶我不能使用 ZipFile.SaveSelfExtractor(Response.OutputStream, options)
之类的东西来做同样的事情。根据 docs,接收流的 SaveSelfExtractor 没有重载。
我可以在网上找到的例子解释了
- 我如何才能 create my own stub 并先将其写回到流中,然后将 zip 存档写入同一流之上。
- 如何temporarily store the sfx on the server,然后使用 FileStream 将其写回客户端。
但我不需要也不想在服务器上临时存储 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();
}
}
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);
}
我将此张贴给后代。这是我能想到的最好的解决方案。欢迎其他人提供更好的解决方案。
[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();
}