Impossible d'accéder à un flux fermé lors de la création d'un fichier texte téléchargeable dans ASP MVC 3

Je tente d'inviter un fichier texte téléchargeable (.txt), mais je reçois cette erreur:

Impossible d'accéder à un flux fermé.

J'ai regardé des questions simulaires ici: Impossible D'Accéder Au Flux Fermé Mais il n'était pas très utile.

Voici mon code:

    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);
    }

Mise à jour (copie de travail):

Cela me donne un fichier texte vide.

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);
}
25
demandé sur Community 2011-08-22 23:33:59

4 réponses

C'est correct, lorsque vous enveloppez un flux dans un autre flux, l'appel à .Close() ou .Dispose() sur l'un d'eux éliminera le flux entier. Dans ce cas, l'encapsulation de MemoryStream dans un StreamWriter signifie que lorsque l'instruction using termine, les StreamWriter et MemoryStream sont tous deux éliminés.

Ma conjecture est que puisque vous renvoyez un FileStreamResult l'encapsulation File fermera le flux pour vous après que le flux ne soit plus utilisé. Dans ce cas, vous ne voulez pas utiliser l'instruction using et voulez laisser le flux ouvert lors du retour.

Mise à JOUR

Comme un flux est un accès direct, vous devez voir le flux au début pour permettre la lecture des données.

stream.Seek(0, SeekOrigin.Begin);
42
répondu Joshua 2011-08-22 20:51:24

Supprimez simplement cette instruction using - vous passez une référence d'objet disposé à la méthode File et c'est la raison pour laquelle vous obtenez une exception. De MSDN ,

L'objet StreamWriter appelle Dispose sur L'objet Stream fourni lorsque StreamWriter.Dispose est appelé.

Je crois que File va disposer du flux par lui-même après utilisation (non vérifié en regardant le code source).

Mise à jour:

writer.Flush(); avant déclaration de retour devrait vous aider

7
répondu archil 2011-08-22 20:08:42

Remplacez le type FileStreamResult sur votre action par FileResult.

1
répondu mare 2011-08-22 20:44:28

Vous devez définir la position du memorystream à 0 avant de l'utiliser dans votre FileStreamResult, sinon il sera lu à partir de la position actuelle (C'est-à-dire la fin du flux).

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

Juste eu la même chose.

Je sais que ce fil est ancien, espérant juste aider les autres ayant le même problème.

1
répondu Julian 2013-07-06 12:27:15