Не удается получить доступ к закрытому потоку при создании загружаемого текстового файла в ASP MVC 3
Я пытаюсь запросить загружаемый текстовый файл (.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);
}
Ответы
Ответ 1
Это верно, когда вы переносите поток в другой поток, вызов .Close()
или .Dispose()
для любого из них будет уничтожать весь поток. В этом случае обертка MemoryStream
в StreamWriter
означает, что когда оператор using
завершает StreamWriter
и MemoryStream
, оба расположены.
Моя догадка заключается в том, что вы возвращаете FileStreamResult
инкапсулирующий File
закроет поток для вас после того, как поток больше не будет использоваться. В этом случае вы не хотите использовать оператор using
и захотите оставить поток открытым при его возврате.
UPDATE
Поскольку поток представляет собой прямой доступ, вам нужно будет увидеть поток обратно в начало, чтобы позволить считывать данные.
stream.Seek(0, SeekOrigin.Begin);
Ответ 2
Просто удалите этот оператор using
- вы передаете ссылку на объект в метод File
, и вы объяснили причину исключения. Из MSDN,
Объект StreamWriter вызывает Dispose на предоставленном объекте Stream когда вызывается StreamWriter.Dispose.
Я полагаю, что File
будет утилизировать поток сам по себе после использования (не проверяется, глядя на исходный код).
UPDATE:
writer.Flush();
перед возвратом должно помочь вам
Ответ 3
Замените тип FileStreamResult
на действие с помощью FileResult
.
Ответ 4
Вы должны установить положение запоминающего потока на 0 перед его использованием в файле FileStreamResult, иначе он будет считан из текущей позиции (IE конец потока).
stream.Position = 0;
return File(stream, "text/plain", name);
Просто одно и то же.
Я знаю, что эта ветка древняя, просто надеясь помочь другим, имеющим ту же проблему.