Comment puis-je copier le contenu d'un flux à un autre?
Quel est le meilleur moyen pour copier le contenu d'un flux à un autre? Est-il un utilitaire standard méthode pour cela?
- Peut-être plus important encore, à ce point, comment avez-vous copier le contenu "streamably", ce qui signifie qu'il ne copie que les cours d'eau de source comme quelque chose qui consomme le flux de destination...?
InformationsquelleAutor Anton | 2008-10-23
Vous devez vous connecter pour publier un commentaire.
De .NET 4.5, il est le
Stream.CopyToAsync
méthodeCela renvoie un
Tâche
qui peut être poursuivi sur une fois rempli, comme suit:Note que selon l'endroit où l'appel à
CopyToAsync
, le code qui suit peut ou ne peut pas continuer sur le même thread qui l'a appelée.La
SynchronizationContext
qui a été capturé lors de l'appel deattendre
permettra de déterminer quel est le fil que la suite sera exécutée.En outre, cet appel (et c'est un détail d'implémentation sous réserve de modification) encore des séquences de lectures et d'écritures (il n'a tout simplement pas perdre un fils de blocage sur les I/O d'achèvement).
De .NET 4.0, il est le
Stream.CopyTo
méthodePour .NET 3.5 et avant
N'est il pas tout cuit dans le cadre de l'aider avec cela; vous devez copier le contenu manuellement, comme suit:
Note 1: Cette méthode vous permettra de faire rapport sur les progrès (x octets lu jusqu'à présent ...)
Note 2: Pourquoi utiliser un fixe taille de la mémoire tampon et pas
input.Length
? Parce que la Longueur peut ne pas être disponible! À partir de la docs:input.CanRead
etoutput.CanWrite
?input
était unMemoryStream
-- ne pas l'avis de votre commentaire, mais a été en mesure de fixer à l'aide.WriteTo
plutôt que.CopyTo
. Je pense que votre suggestion, vous devez également vérifier.CanSeek
avant d'essayer de les chercher.81920
octets, et non pas32768
await input.CopyToAsync(output)
êtreawait input.CopyToAsync(output).ContinueWith(t => /*do something with output*/);
? Je pense que ce plus de sens, car il est probable que le développeur veut travailler avec le flux de sortie.MemoryStream a .WriteTo(outstream);
et .NET 4.0 est .CopyTo normal objet de flux de données.
.NET 4.0:
J'utilise la suite des méthodes d'extension. Ils ont optimisé les surcharges pour lorsqu'un flux est un MemoryStream.
Les questions de base que se différencient les implémentations de "CopyStream" sont:
Les réponses à ces questions entraîner très différentes implémentations de CopyStream et sont dépendantes de ce type de flux que vous avez et ce que vous essayez d'optimiser. Le "meilleur" de la mise en œuvre serait même besoin de savoir ce matériel spécifique les cours d'eau de la lecture et de l'écriture à.
Il est en fait, une moins lourde façon de faire un stream copy. Prenez note toutefois, que cela implique que vous pouvez stocker la totalité du fichier en mémoire. N'essayez pas de les utiliser si vous travaillez avec des fichiers qui vont de plusieurs centaines de méga-octets ou plus, sans précaution.
REMARQUE: Il se peut également que certains problèmes concernant les données binaires et les encodages de caractères.
.NET Framework 4 introduire de nouvelles "CopyTo" méthode de la Classe de Flux de Système.IO espace de noms. En utilisant cette méthode, nous pouvons copier un flux à un autre de différentes classe de flux.
Ici est un exemple pour cela.
Malheureusement, il n'y a pas vraiment de solution simple. Vous pouvez essayer quelque chose comme ça:
Mais le problème avec qui que la mise en œuvre différente de la classe de Flux peut se comporter différemment si il n'y a rien à lire. Un flux de lecture d'un fichier à partir d'un disque dur local sera probablement bloquer jusqu'à ce que la lecture operaition a lu suffisamment de données à partir du disque de remplissage de la mémoire tampon et ne reviennent moins de données si elle atteint la fin de fichier. D'autre part, un flux de lecture depuis le réseau pourrait revenir moins de données, même si il y a plus de gauche pour être reçu.
Toujours consulter la documentation spécifique de la classe de flux que vous utilisez avant d'utiliser une solution générique.
Il y a peut être un moyen de le faire plus efficacement, en fonction du type de flux que vous travaillez avec. Si vous pouvez convertir un ou deux de vos flux à un MemoryStream, vous pouvez utiliser le GetBuffer méthode à travailler directement avec un tableau d'octets pour représenter vos données. Cela vous permet d'utiliser des méthodes de type Array.CopyTo, qui abstraction de toutes les questions soulevées par fryguybob. Vous pouvez seulement de la confiance .NET pour connaître le meilleur moyen pour copier les données.
si vous voulez une procdure pour copier un flux de données vers d'autres celui que nick a posté c'est bien, mais il manque la position de réinitialisation, il devrait être
mais si c'est dans l'exécution pas à l'aide d'une procédure vous shpuld utilisation de flux de mémoire
Puisque aucune de ces réponses ont couvert de manière asynchrone de la copie à partir d'un flux à un autre, ici, c'est un modèle que j'ai utilisé avec succès dans une redirection de port de l'application pour copier des données d'un flux réseau à l'autre. Il manque la gestion des exceptions pour souligner le motif.
Pour .NET 3.5 et avant d'essayer :
Facile et sûr - se faire de nouveaux flux de source d'origine: