IonicZip / DotNetZip Невозможно получить доступ к закрытому файлу.context.Response.OutputStream - PullRequest
1 голос
/ 03 февраля 2012

У меня есть *.ashx (обработчик) с этим кодом:

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?Сообщение об исключении: Невозможно получить доступ к закрытому файлу

1 Ответ

2 голосов
/ 03 февраля 2012

Проблема в том, что вы заключаете поток в оператор использования. В конце оператора 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);
    }
}
...