Comment puis-je enregistrer un flux de données dans un fichier en C#?
J'ai un StreamReader
objet que j'ai initialisé avec un ruisseau, maintenant, je veux enregistrer ce flux sur le disque (le flux peut être un .gif
ou .jpg
ou .pdf
).
Code Existant:
StreamReader sr = new StreamReader(myOtherObject.InputStream);
- J'ai besoin de le sauvegarder sur le disque (j'ai le nom de fichier).
- Dans l'avenir, je peut être utile de stocker ce à SQL Server.
J'ai le type d'encodage aussi, dont j'aurais besoin si je de les stocker dans SQL Server, correct?
Vous devez vous connecter pour publier un commentaire.
Comme l'a souligné Tilendor dans Jon Skeet réponse, les ruisseaux ont un
CopyTo
méthode depuis .NET 4.Ou avec la
using
syntaxe:myOtherObject.InputStream.Seek(0, SeekOrigin.Begin)
si vous n'êtes pas déjà au début ou vous n'aurez pas de copier l'intégralité du flux de données.fileStream
Vous ne doit pas utilisation
StreamReader
pour les fichiers binaires (comme le format gif ou jpg).StreamReader
est pour texte de données. Vous aurez presque certainement de perdre des données si vous l'utilisez pour des données binaires arbitraires. (Si vous utilisez l'Encodage.GetEncoding(28591) vous serez probablement d'accord, mais quel est le point?)Pourquoi avez-vous besoin d'utiliser un
StreamReader
à tous? Pourquoi ne pas tout simplement garder les données binaires comme données binaires et de l'écrire sur le disque (ou SQL) en tant que données binaires?EDIT: Comme cela semble être quelque chose que les gens veulent voir... si vous ne veulent juste de copier un flux à un autre (par exemple, pour un fichier) utiliser quelque chose comme ceci:
De l'utiliser pour faire un dump d'un flux vers un fichier, par exemple:
Noter que
Stream.CopyTo
a été introduit en .NET 4, servant essentiellement le même but.GetResponseStream
sur la réponse...File.Create
, mais je pourrais faire unusing
déclaration qui a été commeusing (FileStream fs = new FileStream(destPath, FileMode.CreateNew, FileAccess.Write)
et ajouterCopyStream(stream, fs);
en elle.File.Create
de WPF avec pas de problèmes.Create
s'en va, donc je ne pourrais pas vous dire ce que mon erreur a été, mais ce n'était pas de me donner intellisense quand je l'avais alors le type de la première parenthèse après, avant, ni de me donner une lecture lors du survol d'File
. Suppose que c'était juste un clin VS bug.using
directive pourSystem.IO
...stream
objet dans leusing(){}
support. Votre méthode n'a pas créer le flux de données, de sorte qu'il ne devrait pas en disposer.FileStream
au lieu de l'aide, sinon il sera conservé jusqu'à ce qu'elle est nettoyée.File.WriteAllBytes(destinationFilePath, input.ToArray());
. Dans mon cas,input
est unMemoryStream
venant de l'intérieur d'unZipArchive
.File.WriteAllBytes(destinationFilePath, input.ToArray());
. Dans mon cas,input
est unMemoryStream
venant de l'intérieur d'unZipArchive
.stream.Seek(0, SeekOrigin.Begin);
Je n'ai pas toutes les réponses à l'aide de
CopyTo
, où peut-être les systèmes à l'aide de l'application pourrait ne pas avoir été mis à niveau .NET 4.0+. Je sais que certains voudraient forcer les gens à mettre à niveau, mais la compatibilité est aussi très agréable, trop.Autre chose, je ne suis pas à l'aide d'un flux de copier à partir d'un autre flux en premier lieu. Pourquoi ne pas simplement faire:
Une fois que vous avez les octets, vous pouvez facilement écrire dans un fichier:
Ce code fonctionne car je l'ai testé avec une
.jpg
fichier, mais je dois admettre que j'ai utilisé uniquement avec des fichiers de petite taille (moins de 1 MO). Un cours d'eau, pas de la copie entre les flux, aucun codage nécessaire, il suffit d'écrire les octets! Pas besoin de compliquer les choses avecStreamReader
si vous disposez déjà d'un ruisseau, vous pouvez convertir lebytes
directement avec.ToArray()
!Seulement inconvénients potentiels que je peux voir dans cette façon de faire est si il y a un gros fichier que vous avez, de l'avoir comme un flux et à l'aide de
.CopyTo()
ou équivalent permetFileStream
le lire au lieu d'utiliser un tableau d'octets et de la lecture les octets un par un. Il pourrait être plus lente, faisant de cette façon, comme un résultat. Mais il ne faut pas étouffer depuis le.Write()
méthode de laFileStream
poignées écrit les octets, et c'est seulement en faisant un octet à la fois, afin de ne pas obstruer la mémoire, sauf que vous devrez avoir assez de mémoire pour contenir le flux en tant quebyte[]
objet. Dans ma situation, où j'ai utilisé cette, d'obtenir uneOracleBlob
, j'ai dû aller à unbyte[]
, il était assez petit, et d'ailleurs, il n'y avait pas de streaming disponible pour moi, de toute façon, je viens d'envoyer mon octets à ma fonction, ci-dessus.Une autre option, à l'aide d'un ruisseau, serait de l'utiliser avec Jon Skeet est
CopyStream
fonction qui était dans un autre post, ce n'utiliseFileStream
de prendre le flux d'entrée et de créer le fichier directement. Il n'utilise pasFile.Create
, comme il l'a fait (qui au départ semblait être problématique pour moi, mais plus tard trouvé que c'était probablement juste un VS bug...).Close
en raison deusing()
inputStream.Close()
, regardez à nouveau -inputStream
est envoyé en tant que variable. Leusing
est sur lepath+filename
flux de sortie. Si vous parliez defs.Close()
dans le milieu de lausing
, désolé, vous avez été correct à ce sujet et j'ai supprimé cette.Pourquoi ne pas utiliser un objet FileStream?
byte[]
, je pense qu'il serait rare que vous seriez en streaming un 1 GO+ blob dans un fichier...sauf si vous avez un site qui maintient DVD torrents... de Plus, la plupart des ordinateurs ont au moins 2 GO de RAM disponible ces jours-ci, de toute façon....Mise en garde est valable, mais je pense que c'est un cas où il est probablement assez "bon" pour la plupart des emplois.FileStream
- nice!Une autre option est d'obtenir le flux à un
byte[]
et l'utilisationFile.WriteAllBytes
. Ceci devrait faire:En l'enveloppant dans une extension de la méthode donne de meilleurs de nommage: