Save and load MemoryStream to/from a file

元气小坏坏 提交于 2019-11-26 06:26:00

You may use MemoryStream.WriteTo or Stream.CopyTo (supported in framework version 4.5.2, 4.5.1, 4.5, 4) methods to write content of memory stream to another stream.

memoryStream.WriteTo(fileStream);

Update:

fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);

Assuming that MemoryStream name is ms.

This code writes down MemoryStream to a file:

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();
}

and this reads a file to a 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+, You can simply copy FileStream to MemoryStream and reverse as simple as this:

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

And the Reverse (MemoryStream to FileStream):

using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
    ms.CopyTo(file);

The stream should really by disposed of even if there's an exception (quite likely on file I/O) - using clauses are my favourite approach for this, so for writing your MemoryStream, you can use:

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

And for reading it back:

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);
}

If the files are large, then it's worth noting that the reading operation will use twice as much memory as the total file size. One solution to that is to create the MemoryStream from the byte array - the following code assumes you won't then write to that stream.

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

My research (below) shows that the internal buffer is the same byte array as you pass it, so it should save memory.

byte[] testData = new byte[] { 104, 105, 121, 97 };
var ms = new MemoryStream(testData, 0, 4, false, true);
Assert.AreSame(testData, ms.GetBuffer());

For anyone looking for the short versions:

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

File.WriteAllBytes("1.dat", memoryStream.ToArray()); 

The combined answer for writing to a file can be;

MemoryStream ms = new MemoryStream();    
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();

For loading a file, I like this a lot better

MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
    fs.CopyTo(ms);
}
Vadim Gremyachev

Save into a file

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

Load from a file

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

where

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;
        }
    }
}

Originally the implementation of this class has been posted here

and

[Serializable]
public class Car
{
    public string Name;
}

I use a Panel Control to add a image or even stream video, but you can save the image on SQL Server as Image or MySQL as largeblob. This code works for me a lot. Check it out.

Here you save the 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();

And here you can load, but I used a PictureBox Control.

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

Hope helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!