Je sérialise une structure en un MemoryStream
et je souhaite enregistrer et charger la structure sérialisée.
Alors, comment enregistrer un MemoryStream
dans un fichier et le recharger à partir du fichier?
Je sérialise une structure en un MemoryStream
et je souhaite enregistrer et charger la structure sérialisée.
Alors, comment enregistrer un MemoryStream
dans un fichier et le recharger à partir du fichier?
Réponses:
Vous pouvez utiliser des méthodes MemoryStream.WriteTo
ou 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.WriteTo(fileStream);
Mettre à jour:
fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);
[file|memory]Stream.Seek(0, SeekOrigin.Begin);
avant CopyTo
définira la position actuelle à 0, ce qui CopyTo
copiera le flux complet.
En supposant que le nom MemoryStream est ms
.
Ce code écrit 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 cela lit un fichier dans 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 vers MemoryStream et inverser aussi simple 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);
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:
using (FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write)) {
memoryStream.WriteTo(file);
}
Et pour le 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 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 = new MemoryStream(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 = new byte[] { 104, 105, 121, 97 };
var ms = new MemoryStream(testData, 0, 4, false, true);
Assert.AreSame(testData, ms.GetBuffer());
La réponse combinée pour écrire dans un fichier peut être;
MemoryStream ms = new MemoryStream();
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();
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());
Charger depuis 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;
}
}
}
À l'origine, l'implémentation de cette classe a été publiée ici
et
[Serializable]
public class Car
{
public string Name;
}
Pour charger un fichier, j'aime beaucoup mieux cela
MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
fs.CopyTo(ms);
}
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 = 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é un contrôle PictureBox.
MemoryStream ms = new MemoryStream(picarr);
ms.Seek(0, SeekOrigin.Begin);
fotos.pictureBox1.Image = System.Drawing.Image.FromStream(ms);
L'espoir aide.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
namespace ImageWriterUtil
{
public class ImageWaterMarkBuilder
{
//private ImageWaterMarkBuilder()
//{
//}
Stream imageStream;
string watermarkText = "©8Bytes.Technology";
Font font = new System.Drawing.Font("Brush Script MT", 30, FontStyle.Bold, GraphicsUnit.Pixel);
Brush brush = new SolidBrush(Color.Black);
Point position;
public ImageWaterMarkBuilder AddStream(Stream imageStream)
{
this.imageStream = imageStream;
return this;
}
public ImageWaterMarkBuilder AddWaterMark(string watermarkText)
{
this.watermarkText = watermarkText;
return this;
}
public ImageWaterMarkBuilder AddFont(Font font)
{
this.font = font;
return this;
}
public ImageWaterMarkBuilder AddFontColour(Color color)
{
this.brush = new SolidBrush(color);
return this;
}
public ImageWaterMarkBuilder AddPosition(Point position)
{
this.position = position;
return this;
}
public void CompileAndSave(string filePath)
{
//Read the File into a Bitmap.
using (Bitmap bmp = new Bitmap(this.imageStream, false))
{
using (Graphics grp = Graphics.FromImage(bmp))
{
//Determine the size of the Watermark text.
SizeF textSize = new SizeF();
textSize = grp.MeasureString(watermarkText, font);
//Position the text and draw it on the image.
if (position == null)
position = new Point((bmp.Width - ((int)textSize.Width + 10)), (bmp.Height - ((int)textSize.Height + 10)));
grp.DrawString(watermarkText, font, brush, position);
using (MemoryStream memoryStream = new MemoryStream())
{
//Save the Watermarked image to the MemoryStream.
bmp.Save(memoryStream, ImageFormat.Png);
memoryStream.Position = 0;
// string fileName = Path.GetFileNameWithoutExtension(filePath);
// outPuthFilePath = Path.Combine(Path.GetDirectoryName(filePath), fileName + "_outputh.png");
using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
{
byte[] bytes = new byte[memoryStream.Length];
memoryStream.Read(bytes, 0, (int)memoryStream.Length);
file.Write(bytes, 0, bytes.Length);
memoryStream.Close();
}
}
}
}
}
}
}
Utilisation: -
ImageWaterMarkBuilder.AddStream(stream).AddWaterMark("").CompileAndSave(filePath);
MemoryStream
?