使用base64编码的内容从XML创建ZipArchive

时间:2015-02-23 04:18:34

标签: c# asp.net zip linq-to-xml

我正在动态创建XML文件。 其中一个节点包含一个编码为BASE64字符串的ZIP文件。

然后我创建另一个ZIP文件。 我添加了这个XML文件和一些其他JPEG文件。 我将文件输出到浏览器。

我无法打开FINAL ZIP文件。 我得到:" Windows无法打开该文件夹。压缩(压缩)文件夹' c:\ path \ file.zip'无效。"

我能够将原始XML文件保存到文件系统中。 我可以打开该XML文件,解码ZIP节点并保存到文件系统。 然后,我可以毫无问题地打开Zip文件。

我可以创建最终的ZIP文件,OMIT我的XML文件,ZIP文件没有问题。

我似乎只有一个问题,我试图压缩一个XML文件,该文件的ZIP节点编码为BASE64字符串。

有什么想法吗?代码snipets如下。重编辑。

XDocument xDoc = new XDocument();
XDocument xDocReport = new XDocument();
XElement xNodeReport;

using (FileStream fsData = new FileStream(strFullFilePath, FileMode.Open, FileAccess.Read)) {
    xDoc = XDocument.Load(fsData);

xNodeReport = xDoc.Element("Data").Element("Reports").Element("Report");

//SNIP
//create XDocument xDocReport 
//SNIO

  using (MemoryStream zipInMemoryReport = new MemoryStream()) {
    using (ZipArchive zipFile = new ZipArchive(zipInMemoryReport, ZipArchiveMode.Update)) {
    //Add REPORT to ZIP file
    ZipArchiveEntry entryReport = zipFile.CreateEntry("data.xml");
      using (StreamWriter writer = new StreamWriter(entryReport.Open())) {
        writer.Write(xDocReport.ToString());
      } //END USING report entry
    }
    xNodeReport.Value = System.Convert.ToBase64String(zipInMemoryReport.GetBuffer());

  //I am able to write this file to disk and manipulate it no problem.
  //File.WriteAllText("c:\\users\\snip\\desktop\\Report.xml",xDoc.ToString());

  }

  //create ZIP for response
  using (MemoryStream zipInMemory = new MemoryStream()) {
    using (ZipArchive zipFile = new ZipArchive(zipInMemory, ZipArchiveMode.Update)) {

    //Add REPORT to ZIP file
    ZipArchiveEntry entryReportWrapper = zipFile.CreateEntry("Report.xml");

    //THIS IS THE STEP THAT makes the Zip "invalid".  Although i can open and manipulate this source file no problem.
    //********
      using (StreamWriter writer = new StreamWriter(entryReportWrapper.Open())) {
        xDoc.Save(writer);
      } 

    //Add JPEG(s) to report
    //Create Charts
    if (chkDLSalesPrice.Checked) {chartDownloadSP.SaveImage(entryChartSP.Open(), ChartImageFormat.Jpeg);}
    if (chkDLSalesDOM.Checked) {chartDownloadDOM.SaveImage(entryChartDOM.Open(), ChartImageFormat.Jpeg);}
    if (chkDLSPLP.Checked) {chartDownloadSPLP.SaveImage(entryChartSPLP.Open(), ChartImageFormat.Jpeg);}
    if (chkDLSPLP.Checked) {chartDownloadLP.SaveImage(entryChartLP.Open(), ChartImageFormat.Jpeg);}

  } // END USING ziparchive

Response.Clear();
Response.AppendHeader("content-disposition", "attachment; filename=file.zip");
Response.ContentType = "application/zip";
Response.BinaryWrite(zipInMemory.GetBuffer());
Response.End();

1 个答案:

答案 0 :(得分:1)

如果没有a good, minimal, complete code example,就无法确定代码中有哪些错误。但是您发布的代码段中至少有两个明显的错误,其中一个错误很容易导致“.zip”无效错误:

  1. 在语句writer.Write(xDocReport.ToString());中,变量xDocReport尚未初始化为任何有用的内容,至少在您发布的代码中没有。因此,您将在存档中获得一个空的XML文档。
  2. 由于代码示例不完整,您可能只是在问题中的代码示例中省略了该变量的初始化。在任何情况下,即使你不这样做,只会导致存档中的空XML文档,而不是无效的存档。

    虽然更有问题......

    1. 您在GetBuffer()个对象上调用了MemoryStream,而不是ToArray()。你想要后者。前者获取MemoryStream对象的整个后备缓冲区,包括超过有效流末尾的未初始化字节。由于有效的.zip文件在文件末尾包含CRC值,因此添加超出该值的额外数据会导致任何尝试将文件作为.zip存档读取而错过正确的CRC,而是读取未初始化的数据。
    2. 将来自GetBuffer()的来电替换为ToArray()来代替。

      如果以上内容无法解决您的问题,则应修改帖子,以提供更好的代码示例。


      最后一条评论:当您要用另一个对象替换该对象时,将xDoc变量初始化为空XDocument对象是没有意义的(例如通过调用XDocument.Load() )。