Невозможно получить доступ к закрытому потоку при создании загружаемого текстового файла в ASP MVC 3 - PullRequest
26 голосов
/ 22 августа 2011

Я пытаюсь запросить загружаемый текстовый файл (.txt), но получаю эту ошибку:

Невозможно получить доступ к закрытому потоку.

Я смотрелСимуляционные вопросы здесь: Невозможно получить доступ к закрытому потоку Но это было не очень полезно.

Вот мой код:

    private FileStreamResult Export()
    {
        string name = "filename.txt";

        MemoryStream stream = new MemoryStream();
        using (StreamWriter writer = new StreamWriter(stream))
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("A text...");
            writer.WriteLine(sb.ToString());
        }

        return File(stream, "text/plain", name);
    }

ОБНОВЛЕНИЕ (рабочая копия):

Это дает мне пустой текстовый файл.

private FileResult Export()
{
    string name = "filename.txt";

    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);

    StringBuilder sb = new StringBuilder();
    sb.Append("A text...");
    writer.WriteLine(sb.ToString());

    writer.Flush();
    stream.Seek(0, SeekOrigin.Begin);

    return File(stream, "text/plain", name);
}

Ответы [ 4 ]

46 голосов
/ 22 августа 2011

Это правильно, когда вы помещаете поток в другой поток, вызов .Close() или .Dispose() для любого из них приведет к удалению всего потока. В этом случае перенос MemoryStream в StreamWriter означает, что после завершения оператора using оба значения StreamWriter и MemoryStream удаляются.

Полагаю, поскольку вы возвращаете FileStreamResult, инкапсуляция File закроет вам поток после того, как поток больше не используется. В этом случае вы не хотите использовать оператор using и захотите оставить поток открытым при его возврате.

UPDATE

Поскольку поток является прямым доступом, вам нужно увидеть его в начале, чтобы можно было считывать данные обратно.

stream.Seek(0, SeekOrigin.Begin);
7 голосов
/ 22 августа 2011

Просто удалите этот оператор using - вы передаете ссылку на удаленный объект методу File, и именно поэтому вы получаете исключение. От MSDN ,

Объект StreamWriter вызывает Dispose для предоставленного объекта Stream когда вызывается StreamWriter.Dispose.

Я полагаю, File самостоятельно утилизирует поток после использования (не проверено при просмотре исходного кода).

UPDATE

writer.Flush(); перед возвратом заявление должно помочь вам

3 голосов
/ 06 июля 2013

Вы должны установить позицию потока памяти в 0, прежде чем использовать ее в вашем FileStreamResult, в противном случае он будет считан из текущей позиции (т.е. конец потока).

stream.Position = 0;
return File(stream, "text/plain", name);

Просто было то же самое.

Я знаю, что эта ветка древняя, просто надеюсь помочь другим, имеющим ту же проблему.

1 голос
/ 23 августа 2011

Замените тип FileStreamResult в вашем действии на FileResult.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...