Сохраните и загрузите MemoryStream в / из файла - PullRequest
243 голосов
/ 24 декабря 2011

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

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

Ответы [ 8 ]

324 голосов
/ 24 декабря 2011

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

memoryStream.WriteTo(fileStream);

Обновление:

fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);
236 голосов
/ 24 декабря 2011

Предполагая, что имя 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);
59 голосов
/ 07 февраля 2013

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

Если файлы большие, то стоит отметить, что операция чтения будет использовать вдвое больше памяти, чем общий размер файла .Одним из решений этой проблемы является создание 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());
32 голосов
/ 22 ноября 2016

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

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

File.WriteAllBytes("1.dat", memoryStream.ToArray()); 
18 голосов
/ 31 января 2013

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

MemoryStream ms = new MemoryStream();    
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();
14 голосов
/ 10 октября 2013

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

MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
    fs.CopyTo(ms);
}
13 голосов
/ 09 ноября 2015

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

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;
}
3 голосов
/ 06 октября 2016

Я использую Panel Control для добавления изображения или даже потокового видео, но вы можете сохранить изображение на 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 Control.

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

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

...