10
votes

Comment puis-je clone objet MemorMemstream?

J'ai un objet MemoryStream qui est passé par flux paramètre type ( flux est une classe abstraite en C #).

Je veux le cloner et créer un autre objet MemoryStream Objet un côté avec la position actuelle de l'original et pour créer également un nouveau xmlreader hors de celui-ci, donc je vais être capable de lire son contenu.

C'est ce que j'ai fait, et cela ne fonctionne pas (débogage de la ligne marquée avec // * -> newReader a {non } valeur)
Assomption : Vous êtes à l'intérieur d'une méthode et avez Currentstream de flux référence. xxx


15 commentaires

Quelle est la valeur de newMemoryStream.position avant et après le copyto appel?


@AustinSalonen: les deux sont 0


Si l'avant et après la position sur sur newMemoryStream sont 0, alors rien n'a été copié dans celui-ci - votre flux source est à sa fin avant la copie.


@MLORBETSKEKE: Cela ne peut pas être parce que Jusqu'à présent, j'utilisais l'objet XMLreader pour lire le contenu de Stream, et je me suis arrêté au milieu pour faire le code que j'ai écrit ci-dessus. J'ai été capable de lire des contenus xml, je veux maintenant le même flux du point que j'ai arrêté et nouveau xmlreader à lire davantage


La position est probablement probablement non valide ... Vous semblez utiliser d'autres lecteurs au-dessus de l'original flux - que le lecteur peut être en train de faire des lectures de blocs et la position ne serait pas une valeur exacte dans laquelle vous avez cessé de lire. Donc, vous devez vérifier si la position est correcte ou la force à être correcte d'une manière ou d'une autre ...


@Javasa puisque xmlreader lit dans des morceaux tamponnés dans le flux source, où vous arrêtez de lire XML, ce n'est pas nécessairement là que vous vous arrêtez dans le flux. Pourriez-vous vérifier position et longueur sur flux juste avant le copyto ligne?


@MlorBetske: Je vais vérifier comme vous l'avez suggéré maintenant


OK, leur valeur est de 972 avant et après copyto


@Javasa si, à la fois que vous voulez dire position et longueur , votre flux a déjà été lu à sa fin par l'original xmlreader , vous aurez besoin de Pour calculer la position que vous souhaitez vraiment et l'affecter à flux.position. / code> avant de faire le copyto


oui les deux est position et longueur , il est bizarre car je peux vous dire exactement à quelle étiquette d'élément je suis arrêté avant de faire le code ci-dessus qui fait partie du code de la méthode ci-dessus.


@ALEXEILEEVENKOV: Je vais essayer d'arriver au même endroit en créant d'abord un nouveau xmlreader hors de neuf Morthstream qui est une copie du deuxième flux déjà parcouru. Ensuite, itérant nouveau ruisseau jusqu'à la balise que je m'arrêtais dans l'original, faisais ce dont j'ai besoin et jette ce flux et ce lecteur. Je suppose que je pourrai revenir à l'original xmlreader avec le flux d'origine et continuer à lire, car les deux flux et les deux lecteurs sont des objets distincts et je tiens leurs références aussi.


@Alexeilevenkov: Je voulais juste savoir, en tant que développeur dans Microsoft pourquoi faire une tâche aussi simple est censée être tellement compliquée? :)


Avoir 2 lecteurs sur le même flux n'est pas très "simple" Tâche ... Les flux de couches / lecteurs sont tout simplement pas conçus pour permettre un tel scénario: trouvez la position dans le flux de niveau le plus bas sur tout décalage particulier du lecteur / flux externe. C'est à dire. Envisagez des flux de compression - la lecture du flux externe ne correspond pas directement à des changements de position de la diffusion intérieure ....


@Alexeilevenkov: L'idée est presque que vous avez écrite: avoir deux lecteurs sur Deux flux , pas un seul flux. Mais un flux est une copie de l'autre. J'espère que ce n'est pas si compliqué, et je serai heureux si vous me référez au flux de compression , malheureusement, je ne connais pas ce sujet.


(Streams de compression - recherche de gzipsteam - il enveloppe le flux intérieur pour compresser / décompresser sur lecture / écriture). Ma compréhension que vous vouliez que le deuxième flux commence à partir de la position actuelle dans le premier flux. Si vous avez juste besoin de clone de flux entier avec la position de la deuxième série sur 0 - Nouveau MorthStream (((Morthstream) Stream) .toarray ()) Ce qui ne semble pas être suffisamment intéressant pour poser une question ...


3 Réponses :


9
votes

Assurez-vous de réinitialiser la position sur NewMemoryStream comme: xxx

après flux.copyto (NewMemoryStream); mais avant de créer le xmlreader

donc le tout devrait ressembler à ceci: xxx

aussi, puisque vous utilisez un autre lecteur sur Le flux d'origine avant d'entrer cette méthode, assurez-vous que la position du flux source est vraiment là que vous voulez que ce soit.


3 commentaires

Je ne peux pas copier de la position actuelle du flux à NewMemoryStream, je pense avoir besoin de cette option


@Javasa copie commence à la position actuelle du flux copyto est appelé, mais (comme vous l'avez dit dans votre réponse sur votre question), la position de NewMemoryStream est 0 après le copie. Après la copie, le flux cible est à sa fin (ou au moins dans la position de la copie terminée à) - dans ce cas indiquant que rien n'a été copié dessus, probablement parce que le flux source était à sa fin (ou était en soi vide) .


Ce que vous avez dit est correct mais deux autres instructions manquaient, voyez ma réponse.



5
votes

J'ai résolu mon problème! :)
Les choses qui manquent sont marquées avec // * code>. Voici le code tel qu'il devrait être:

var xmlReaderSettings = new XmlReaderSettings();

stream.Position = 0;//*
xmlReaderSettings.IgnoreWhitespace = true;
using (var newMemoryStream = new MemoryStream())
{
    stream.CopyTo(newMemoryStream);
    newMemoryStream.Position = 0;  //*
    using (var newReader = XmlReader.Create(newMemoryStream, xmlReaderSettings))
    {
        newReader.MoveToContent(); //*

        Doing some stuff...
    }
}


0 commentaires

3
votes

Vous pouvez utiliser la méthode d'extension suivante pour cloner un MemorMOstream code>, y compris sa position actuelle et assurer la position de l'original Morthstream code> est réinitialisé à sa position d'origine après le clonage :

public static MemoryStream Clone(this MemoryStream ms) {
    var pos = ms.Position;
    var ms2 = new MemoryStream();
    ms.CopyTo(ms2);
    ms.Position = pos;
    ms2.Position = pos;
    return ms2;
}


0 commentaires