Ich serialisiere eine Struktur in eine MemoryStream
und möchte die serialisierte Struktur speichern und laden.
Also, wie man ein MemoryStream
in eine Datei speichert und es auch wieder aus der Datei lädt?
Ich serialisiere eine Struktur in eine MemoryStream
und möchte die serialisierte Struktur speichern und laden.
Also, wie man ein MemoryStream
in eine Datei speichert und es auch wieder aus der Datei lädt?
Antworten:
Sie können MemoryStream.WriteTo
oder Stream.CopyTo
(in Framework-Version 4.5.2, 4.5.1, 4.5, 4 unterstützt) Methoden verwenden, um Inhalte des Speicherstroms in einen anderen Stream zu schreiben.
memoryStream.WriteTo(fileStream);
Aktualisieren:
fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);
[file|memory]Stream.Seek(0, SeekOrigin.Begin);
bevor CopyTo
die aktuelle Position auf 0 gesetzt, so dass CopyTo
der kompletten Strom kopieren.
Angenommen, der Name MemoryStream lautet ms
.
Dieser Code schreibt MemoryStream in eine Datei:
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();
}
und dies liest eine Datei in einen 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);
}
In .Net Framework 4+ können Sie FileStream einfach in MemoryStream kopieren und so einfach umkehren:
MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read))
file.CopyTo(ms);
Und die Umkehrung (MemoryStream zu FileStream):
using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
ms.CopyTo(file);
ms.ToArray()
Funktion verwenden.
using (...){ }
hat genau den gleichen Effekt.
Der Stream sollte wirklich entsorgt werden, auch wenn es eine Ausnahme gibt (sehr wahrscheinlich bei Datei-E / A). Die Verwendung von Klauseln ist mein bevorzugter Ansatz, sodass Sie zum Schreiben Ihres MemoryStream Folgendes verwenden können:
using (FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write)) {
memoryStream.WriteTo(file);
}
Und zum Zurücklesen:
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);
}
Wenn die Dateien groß sind, ist zu beachten, dass der Lesevorgang doppelt so viel Speicher benötigt wie die gesamte Dateigröße . Eine Lösung hierfür besteht darin, den MemoryStream aus dem Byte-Array zu erstellen. Im folgenden Code wird davon ausgegangen, dass Sie dann nicht in diesen Stream schreiben.
MemoryStream ms = new MemoryStream(bytes, writable: false);
Meine Forschung (unten) zeigt, dass der interne Puffer das gleiche Byte-Array ist, mit dem Sie ihn übergeben, sodass Speicherplatz gespart werden sollte.
byte[] testData = new byte[] { 104, 105, 121, 97 };
var ms = new MemoryStream(testData, 0, 4, false, true);
Assert.AreSame(testData, ms.GetBuffer());
Die kombinierte Antwort zum Schreiben in eine Datei kann sein;
MemoryStream ms = new MemoryStream();
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();
In einer Datei speichern
Car car = new Car();
car.Name = "Some fancy car";
MemoryStream stream = Serializer.SerializeToStream(car);
System.IO.File.WriteAllBytes(fileName, stream.ToArray());
Laden aus einer Datei
using (var stream = new MemoryStream(System.IO.File.ReadAllBytes(fileName)))
{
Car car = (Car)Serializer.DeserializeFromStream(stream);
}
wo
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;
}
}
}
Ursprünglich wurde die Implementierung dieser Klasse hier veröffentlicht
und
[Serializable]
public class Car
{
public string Name;
}
Zum Laden einer Datei gefällt mir das viel besser
MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
fs.CopyTo(ms);
}
Ich verwende ein Bedienfeld, um ein Bild hinzuzufügen oder sogar Videos zu streamen, aber Sie können das Bild auf SQL Server als Image oder MySQL als Largeblob speichern . Dieser Code funktioniert bei mir sehr. Hör zu.
Hier speichern Sie das Bild
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();
Und hier können Sie laden, aber ich habe ein PictureBox-Steuerelement verwendet.
MemoryStream ms = new MemoryStream(picarr);
ms.Seek(0, SeekOrigin.Begin);
fotos.pictureBox1.Image = System.Drawing.Image.FromStream(ms);
Hoffnung hilft.
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();
}
}
}
}
}
}
}
Verwendung :-
ImageWaterMarkBuilder.AddStream(stream).AddWaterMark("").CompileAndSave(filePath);
MemoryStream
?