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?
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);
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);
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());
pour tous ceux qui recherchent les versions courtes:
var memoryStream = new MemoryStream(File.ReadAllBytes("1.dat"));
File.WriteAllBytes("1.dat", memoryStream.ToArray());
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();
Pour charger un fichier, je l'aime beaucoup mieux
MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
fs.CopyTo(ms);
}
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);
}
où
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;
}
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.