2012-02-03 70 views
1

我有一個*.ashx(處理器) 與此代碼:IonicZip/DotNetZip無法訪問已關閉的文件。 context.Response.OutputStream

public void ProcessRequest (HttpContext context) { 
    context.Response.ContentType = "application/zip"; 
    context.Response.AddHeader("Content-Disposition", "attachment; filename=catalog" + DateTime.Now.ToString("yyyy-MM-dd") + ".zip"); 

    // magic happends here to get a DataTable called 'dt' 

    using (ZipFile zip = new ZipFile(Encoding.UTF8)) 
    { 
     foreach (DataRow dr in dt.Rows) 
     { 
      string barCode = "C:/tmp/bc/" + dr["ProductCode"] + ".gif"; 

      if (File.Exists(barCode)) 
      { 
       if (!zip.EntryFileNames.Contains("bc" + dr["ProductCode"] + ".gif")) 
       { 
        try 
        { 
         // this option does not work 
         using (StreamReader sr = new StreamReader(barCode)) 
         { 
          if (sr.BaseStream.CanRead) 
           zip.AddEntry("bc" + dr["ProductCode"] + ".gif", sr.BaseStream); 
         } 
         // but the next line does work... WHY? 
         zip.AddEntry("bc" + dr["ProductCode"] + ".gif", File.ReadAllBytes(barCode)); 
        } 
        catch (Exception ex) 
        { 
         // never hits the catch 
         context.Response.Write(ex.Message); 
        } 
       } 
      } 
     } 
     zip.Save(context.Response.OutputStream); // here is the exception if I use the first option 
    } 
} 

我使用最新版本的http://dotnetzip.codeplex.com/ 有人能向我解釋,爲什麼File.ReadAllBytes做工作和StreamReader確實崩潰當保存到OutputStream? 異常消息是無法訪問已關閉的文件

回答

2

問題是您將流包裝在using語句中。在使用聲明結束時,流被丟棄。

當您致電zip.save時,庫嘗試訪問已關閉的流。 File.ReadAllBytes不會因爲它直接傳遞數據而失敗。

public void ProcessRequest (HttpContext context) { 
context.Response.ContentType = "application/zip"; 
context.Response.AddHeader("Content-Disposition", "attachment; filename=catalog" + DateTime.Now.ToString("yyyy-MM-dd") + ".zip"); 

    using (ZipFile zip = new ZipFile(Encoding.UTF8)) 
    { 
     foreach (DataRow dr in dt.Rows) 
     { 
      string barCode = "C:/tmp/bc/" + dr["ProductCode"] + ".gif"; 

      if (File.Exists(barCode)) 
      { 
       if (!zip.EntryFileNames.Contains("bc" + dr["ProductCode"] + ".gif")) 
       { 
        try 
        { 
         // The file stream is opened here 
         using (StreamReader sr = new StreamReader(barCode)) 
         { 
          if (sr.BaseStream.CanRead) 
           zip.AddEntry("bc" + dr["ProductCode"] + ".gif", sr.BaseStream); 
         } 
         // The file stream is closed here 
        } 
        catch (Exception ex) 
        { 
         // never hits the catch 
         context.Response.Write(ex.Message); 
        } 
       } 
      } 
     } 

     // The closed file streams are accessed here 
     zip.Save(context.Response.OutputStream); 
    } 
}