49 votes

Impossible d'accéder à un Stream fermé d'un memoryStream, comment le rouvrir ?

J'ai une instance de memoryStream et elle est fermée.

J'ai déjà essayé :

memoryStream.Flush();
memoryStream.Position=0;

Pour rouvrir le flux de mémoire mais cela ne fonctionne pas. Comment puis-je rouvrir un flux de mémoire fermé ?

46voto

Greg B Points 206

Vous pouvez cloner l'original et ensuite utiliser le clone, même si l'original a été fermé. Même si l'original est créé avec une capacité de 1000, ToArray() renvoie un tableau de 2 éléments. En revanche, ToBuffer() vous renvoie le tampon entier, ce que vous ne voulez pas.

MemoryStream original = new MemoryStream(1000);
original.WriteByte(4);
original.WriteByte(5);

MemoryStream dolly = new MemoryStream(original.ToArray());
dolly.Seek(0, SeekOrigin.Begin);

31voto

Andrew Pope Points 247

Essayez ceci :

memoryStream = new MemoryStream(memoryStream.ToArray());

13voto

Reed Copsey Points 315315

Comment rouvrir un flux de mémoire fermé ?

Vous ne pouvez pas rouvrir le flux. Si vous devez "réinitialiser" le flux, il suffit de lui attribuer une nouvelle instance :

memoryStream = new MemoryStream();

10voto

RenniePet Points 2388

Il s'agit d'une très vieille question, mais je réagis au fait que la réponse acceptée n'est pas vraiment utile et que la réponse ayant reçu le plus de votes dit que l'utilisation de .ToArray() est meilleure que celle de .GetBuffer(). Je pense que dans de nombreuses situations, voire la plupart, l'utilisation de .GetBuffer() est nettement meilleure que celle de .ToArray().

Voici un exemple du problème de la fermeture d'un flux de mémoire malgré votre désir de continuer à l'utiliser :

  /// <summary>
  /// Method that gets called by ManagedResource.WriteData() in project CodeAnalysis during code 
  /// emitting to get the data for an embedded resource file.
  /// </summary>
  /// <param name="resourceFullFilename">full path and filename for resource file to embed</param>
  /// <returns>MemoryStream containing .resource file data - caller will dispose it</returns>
  private static MemoryStream ProvideResourceData(string resourceFullFilename)
  {
     MemoryStream shortLivedBackingStream = new MemoryStream();
     using (ResourceWriter resourceWriter = new ResourceWriter(shortLivedBackingStream))
     {
        using (ResXResourceReader resourceReader = new ResXResourceReader(resourceFullFilename))
        {
           IDictionaryEnumerator dictionaryEnumerator = resourceReader.GetEnumerator();
           while (dictionaryEnumerator.MoveNext())
           {
              string resourceKey = dictionaryEnumerator.Key as string;
              if (resourceKey != null)  // Should not be possible
                 resourceWriter.AddResource(resourceKey, dictionaryEnumerator.Value);
           }
        }
     }

     return new MemoryStream(shortLivedBackingStream.GetBuffer());
  }

Le site ResourceWriter a besoin d'un flux de sauvegarde, je lui donne donc un flux de mémoire nouvellement créé. Mais lorsque ResourceWriter n'est plus nécessaire, il ferme le flux de sauvegarde. Ensuite, je crée un nouveau MemoryStream basé sur le tampon du flux de sauvegarde, ce qui fonctionne bien, même s'il est fermé.

Dans cette situation, je sais que le programme appelant va utiliser le flux de mémoire fourni pour copier les données dans un autre tampon, puis fermer immédiatement le flux de mémoire. Il n'y a donc pas besoin de créer un nouveau tableau d'octets, et il y a un avantage en termes de performance pour no créer un nouveau tableau d'octets.

Merci à @JoshVarty pour avoir montré comment éviter le problème des MemoryStream qui se ferme ici : https://github.com/dotnet/roslyn/issues/7791

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X