Enregistrer et charger MemoryStream à / à partir d'un fichier

Je sérialise une structure dans un MemoryStream et je veux enregistrer et charger la structure sérialisée.

alors, comment sauvegarder un MemoryStream dans un fichier et aussi le charger à partir du fichier?

207
demandé sur Ashkan Mobayen Khiabani 2011-12-24 14:55:04

8 réponses

vous pouvez utiliser les méthodes MemoryStream.WriteTo ou Stream.CopyTo (supportées dans la version 4.5.2, 4.5.1, 4.5, 4) pour écrire le contenu du flux de mémoire à un autre flux.

memoryStream.WriteTo(fileStream);

mise à jour:

fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);
298
répondu adatapost 2014-06-29 03:38:10

en supposant que le nom de MemoryStream est ms .

ce code inscrit MemoryStream dans un fichier:

using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write)) {
   byte[] bytes = new byte[ms.Length];
   ms.Read(bytes, 0, (int)ms.Length);
   file.Write(bytes, 0, bytes.Length);
   ms.Close();
}

et ceci lit un fichier à un MemoryStream:

using (MemoryStream ms = new MemoryStream())
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read)) {
   byte[] bytes = new byte[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 dans MemoryStream et inverser aussi simplement que ceci:

MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read))
    file.CopyTo(ms);

Et l'Inverse (MemoryStream à FileStream):

using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
    ms.CopyTo(file);
203
répondu Ashkan Mobayen Khiabani 2017-09-05 16:35:56

le flux devrait vraiment être éliminé même s'il y a une exception (très probablement dans le fichier I/O) - l'utilisation de clauses sont mon approche préférée pour cela, donc pour écrire votre MemoryStream, vous pouvez utiliser:

using (FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write)) {
    memoryStream.WriteTo(file);
}

et pour la relire:

using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read)) {
    byte[] bytes = new byte[file.Length];
    file.Read(bytes, 0, (int)file.Length);
    ms.Write(bytes, 0, (int)file.Length);
}

si les fichiers sont volumineux, il est intéressant de noter que l'opération de lecture utilisera deux fois plus de mémoire que la taille totale du fichier . Une solution à cela est pour créer le MemoryStream à partir du tableau d'octets - le code suivant suppose que vous n'écrirez pas dans ce flux.

MemoryStream ms = new MemoryStream(bytes, writable: false);

Mes recherches (ci-dessous) montrent que le tampon interne est le même tableau de bytes que vous le passez, donc il devrait sauver de la mémoire.

byte[] testData = new byte[] { 104, 105, 121, 97 };
var ms = new MemoryStream(testData, 0, 4, false, true);
Assert.AreSame(testData, ms.GetBuffer());
54
répondu Rob Church 2013-10-18 13:11:44

pour tous ceux qui recherchent les versions courtes:

var memoryStream = new MemoryStream(File.ReadAllBytes("1.dat"));

File.WriteAllBytes("1.dat", memoryStream.ToArray()); 
28
répondu Slai 2016-11-22 13:22:19

la réponse combinée pour écrire à un dossier peut être;

MemoryStream ms = new MemoryStream();    
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();
17
répondu Berkay Turancı 2013-06-12 14:53:45

Pour charger un fichier, je l'aime beaucoup mieux

MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
    fs.CopyTo(ms);
}
14
répondu ProVega 2013-10-10 17:41:56

enregistrer dans un fichier

Car car = new Car();
car.Name = "Some fancy car";
MemoryStream stream = Serializer.SerializeToStream(car);
System.IO.File.WriteAllBytes(fileName, stream.ToArray());

charge à partir d'un fichier

using (var stream = new MemoryStream(System.IO.File.ReadAllBytes(fileName)))
{
    Car car = (Car)Serializer.DeserializeFromStream(stream);
}

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace Serialization
{
    public class Serializer
    {
        public static MemoryStream SerializeToStream(object o)
        {
            MemoryStream stream = new MemoryStream();
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, o);
            return stream;
        }

        public static object DeserializeFromStream(MemoryStream stream)
        {
            IFormatter formatter = new BinaryFormatter();
            stream.Seek(0, SeekOrigin.Begin);
            object o = formatter.Deserialize(stream);
            return o;
        }
    }
}

initialement, la mise en œuvre de cette classe a été publiée ici

et

[Serializable]
public class Car
{
    public string Name;
}
10
répondu Vadim Gremyachev 2017-05-23 11:47:29

j'utilise un panneau de contrôle pour ajouter une image ou même un flux vidéo, mais vous pouvez enregistrer l'image sur le serveur SQL comme Image ou MySQL comme largeblob . Ce code fonctionne pour moi. Check it out.

ici vous sauvegardez l'image

MemoryStream ms = new MemoryStream();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); // here you can change the Image format
byte[] Pic_arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(Pic_arr, 0, Pic_arr.Length);
ms.Close();

et ici vous pouvez charger, mais j'ai utilisé une commande PictureBox.

MemoryStream ms = new MemoryStream(picarr);
ms.Seek(0, SeekOrigin.Begin);
fotos.pictureBox1.Image = System.Drawing.Image.FromStream(ms);

Espoir aide.

3
répondu Leinad 2016-10-06 02:17:29