Сохранение и загрузка MemoryStream в / из файла

Я сериализую структуру в MemoryStream и я хочу сохранить и загрузить сериализованную структуру.

Итак, как сохранить MemoryStream в файл и загружать их обратно из файла?

8 ответов


вы можете использовать MemoryStream.WriteTo или Stream.CopyTo (поддерживается в Framework версии 4.5.2, 4.5.1, 4.5, 4) методы записи содержимого памяти потока в другой поток.

memoryStream.WriteTo(fileStream);

обновление:

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

предполагая, что MemoryStream имя ms.

этот код записывает MemoryStream в файл:

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

и это считывает файл в 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);
}

в .Net Framework 4+ Вы можете просто скопировать FileStream в MemoryStream и отменить так просто:

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

и наоборот (MemoryStream в FileStream):

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

поток действительно должен быть удален, даже если есть исключение (вполне вероятно, в файле ввода-вывода) - использование предложений-мой любимый подход для этого, поэтому для написания MemoryStream вы можете использовать:

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

и для чтения его обратно:

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

если файлы большие, то стоит отметить, что операция чтения будет использовать вдвое больше памяти, чем размер файла. Одно из решений-создание потоке MemoryStream от байта array-следующий код предполагает, что вы не будете писать в этот поток.

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

мое исследование (ниже) показывает, что внутренний буфер является тем же самым массивом байтов, как вы передаете его, поэтому он должен сохранить память.

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

для тех, кто ищет короткие версии:

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

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

комбинированный ответ для записи в файл может быть;

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

для загрузки файла мне это нравится намного лучше

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

сохранить в файл

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

загрузить из файла

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

первоначально реализация этого класса была размещена здесь

и

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

Я использую элемент управления панели для добавления изображения или даже потокового видео, но вы можете сохранить изображение на SQL Server как изображения или MySQL как largeblob. Этот код работает для меня. Проверить его.

здесь вы сохраняете изображение

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

и здесь вы можете загрузить, но я использовал элемент управления PictureBox.

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

надеюсь поможет.