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

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

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

Ответ 1

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

memoryStream.WriteTo(fileStream);

Update:

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

Ответ 2

Предполагая, что имя 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 to FileStream):

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

Ответ 3

Поток должен действительно удаляться, даже если есть исключение (скорее всего, в вводе-выводе файлов) - использование предложений - мой любимый подход для этого, поэтому для написания вашего 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 из массива байтов - следующий код предполагает, что вы не будете писать в этот поток.

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

Ответ 4

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

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

Ответ 5

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

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

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

Ответ 6

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

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

Ответ 7

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

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

Ответ 8

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

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

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 Control.

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

Надежда помогает.