Si vous devez enregistrer dans un fichier, pourquoi utilisez-vous un MemoryStream?
Oded
@Oded Que dois-je utiliser? Peux-tu me donner un exemple?
Mahdi Ghiasi
Réponses:
365
Vous pouvez utiliser des méthodes MemoryStream.WriteToou Stream.CopyTo(prises en charge dans la version 4.5.2, 4.5.1, 4.5, 4) pour écrire le contenu du flux de mémoire dans un autre flux.
memoryStream.CopyTo ne semble pas fonctionner pour moi, contrairement à WriteTo. Je pense que c'était peut-être parce que mon memoryStream.Position n'était pas 0
Mark Adamson
10
Oui c'est correct. La différence entre eux est que CopyTo copie à partir de la position actuelle au lieu de toujours partir du début comme WriteTo le fait.
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write)){byte[] bytes =newbyte[ms.Length];
ms.Read(bytes,0,(int)ms.Length);
file.Write(bytes,0, bytes.Length);
ms.Close();}
et cela lit un fichier dans un MemoryStream:
using (MemoryStream ms =newMemoryStream())
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read)){byte[] bytes =newbyte[file.Length];
file.Read(bytes,0,(int)file.Length);
ms.Write(bytes,0,(int)file.Length);}
Dans .Net Framework 4+, vous pouvez simplement copier FileStream vers MemoryStream et inverser aussi simple que ceci:
MemoryStream ms =newMemoryStream();
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read))
file.CopyTo(ms);
Et l'inverse (MemoryStream à FileStream):
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write))
ms.CopyTo(file);
Puis-je vous demander pourquoi vous utilisez FileMode.Create dans l'exemple de lecture vs FileMode.Open?
Philter
6
Dans le premier bloc de code, au lieu de copier manuellement le flux de mémoire dans le tableau, vous pouvez utiliser la ms.ToArray()fonction intégrée.
Gman
5
Il est important de définir ms.Position = 0, sinon le tableau d'octets (et le fichier) contiendra tous les zéros.
Gregory Khrapunovich
1
@ Fernando68 la construction using (...){ }a exactement le même effet.
Fabricio Araujo
2
Tout comme un avertissement pour les autres `` utilisant (FileStream '' et `` ms.CopyTo (fichier) '' définit la position à la fin du fichier et vous devez réinitialiser le flux de mémoire par la suite.
Rebecca
64
Le flux devrait vraiment être éliminé même s'il y a une exception (très probablement sur les E / S de fichier) - l'utilisation de clauses est mon approche préférée pour cela, donc pour écrire votre MemoryStream, vous pouvez utiliser:
using (FileStream file =newFileStream("file.bin",FileMode.Create,FileAccess.Write)){
memoryStream.WriteTo(file);}
Et pour le relire:
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read)){byte[] bytes =newbyte[file.Length];
file.Read(bytes,0,(int)file.Length);
ms.Write(bytes,0,(int)file.Length);}
Si les fichiers sont volumineux, il convient de noter que l'opération de lecture utilisera deux fois plus de mémoire que la taille totale du fichier . Une solution à cela consiste à créer le MemoryStream à partir du tableau d'octets - le code suivant suppose que vous n'écrirez pas alors sur ce flux.
MemoryStream ms =newMemoryStream(bytes, writable:false);
Ma recherche (ci-dessous) montre que le tampon interne est le même tableau d'octets que vous le passez, il devrait donc économiser de la mémoire.
byte[] testData =newbyte[]{104,105,121,97};var ms =newMemoryStream(testData,0,4,false,true);Assert.AreSame(testData, ms.GetBuffer());
Car car =newCar();
car.Name="Some fancy car";MemoryStream stream =Serializer.SerializeToStream(car);System.IO.File.WriteAllBytes(fileName, stream.ToArray());
Charger depuis un fichier
using (var stream =newMemoryStream(System.IO.File.ReadAllBytes(fileName))){Car car =(Car)Serializer.DeserializeFromStream(stream);}
où
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Serialization{publicclassSerializer{publicstaticMemoryStreamSerializeToStream(object o){MemoryStream stream =newMemoryStream();IFormatter formatter =newBinaryFormatter();
formatter.Serialize(stream, o);return stream;}publicstaticobjectDeserializeFromStream(MemoryStream stream){IFormatter formatter =newBinaryFormatter();
stream.Seek(0,SeekOrigin.Begin);object o = formatter.Deserialize(stream);return o;}}}
À l'origine, l'implémentation de cette classe a été publiée ici
Si le fichier est ouvert dans Microsoft Word - existe-t-il un moyen de créer un flux de mémoire à partir de ce fichier? Je reçois une erreur «le fichier est ouvert par un autre processus»
FrenkyB
@FrenkyB Je rencontre aussi beaucoup ça. Si vous avez ouvert le fichier dans Word ou dans une autre application, vous ne pouvez pas le faire. Fermez simplement le fichier dans Word.
Kristopher
@FrenkyB Pouvez-vous faire un File.Copy? J'ai trouvé que cela fonctionne, puis lisez ce fichier dans un flux et supprimez le nouveau fichier ... horrible, mais semble fonctionner.
ridecar2
3
J'utilise un panneau de commande pour ajouter une image ou même flux vidéo, mais vous pouvez enregistrer l'image sur SQL Server comme image ou MySQL comme largeblob . Ce code fonctionne beaucoup pour moi. Vérifiez-le.
Ici, vous enregistrez l'image
MemoryStream ms =newMemoryStream();Bitmap bmp =newBitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);// here you can change the Image formatbyte[]Pic_arr=newbyte[ms.Length];
ms.Position=0;
ms.Read(Pic_arr,0,Pic_arr.Length);
ms.Close();
Et ici, vous pouvez charger, mais j'ai utilisé un contrôle PictureBox.
MemoryStream ms =newMemoryStream(picarr);
ms.Seek(0,SeekOrigin.Begin);
fotos.pictureBox1.Image=System.Drawing.Image.FromStream(ms);
MemoryStream
?Réponses:
Vous pouvez utiliser des méthodes
MemoryStream.WriteTo
ouStream.CopyTo
(prises en charge dans la version 4.5.2, 4.5.1, 4.5, 4) pour écrire le contenu du flux de mémoire dans un autre flux.Mettre à jour:
la source
[file|memory]Stream.Seek(0, SeekOrigin.Begin);
avantCopyTo
définira la position actuelle à 0, ce quiCopyTo
copiera le flux complet.En supposant que le nom MemoryStream est
ms
.Ce code écrit MemoryStream dans un fichier:
et cela lit un fichier dans un MemoryStream:
Dans .Net Framework 4+, vous pouvez simplement copier FileStream vers MemoryStream et inverser aussi simple que ceci:
Et l'inverse (MemoryStream à FileStream):
la source
ms.ToArray()
fonction intégrée.using (...){ }
a exactement le même effet.Le flux devrait vraiment être éliminé même s'il y a une exception (très probablement sur les E / S de fichier) - l'utilisation de clauses est mon approche préférée pour cela, donc pour écrire votre MemoryStream, vous pouvez utiliser:
Et pour le relire:
Si les fichiers sont volumineux, il convient de noter que l'opération de lecture utilisera deux fois plus de mémoire que la taille totale du fichier . Une solution à cela consiste à créer le MemoryStream à partir du tableau d'octets - le code suivant suppose que vous n'écrirez pas alors sur ce flux.
Ma recherche (ci-dessous) montre que le tampon interne est le même tableau d'octets que vous le passez, il devrait donc économiser de la mémoire.
la source
Pour ceux qui recherchent les versions courtes:
la source
La réponse combinée pour écrire dans un fichier peut être;
la source
Enregistrer dans un fichier
Charger depuis un fichier
où
et
la source
Pour charger un fichier, j'aime beaucoup mieux cela
la source
J'utilise un panneau de commande pour ajouter une image ou même flux vidéo, mais vous pouvez enregistrer l'image sur SQL Server comme image ou MySQL comme largeblob . Ce code fonctionne beaucoup pour moi. Vérifiez-le.
Ici, vous enregistrez l'image
Et ici, vous pouvez charger, mais j'ai utilisé un contrôle PictureBox.
L'espoir aide.
la source
Utilisation: -
la source