it-roy-ru.com

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

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

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

238
Mahdi Ghiasi

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

memoryStream.WriteTo(fileStream);

Обновление:

fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);
322
adatapost

Предполагая, что имя 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);
232
Ashkan Mobayen Khiabani

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

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

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

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

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

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

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

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

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

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;
}
13
Vadim Gremyachev

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

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

3
Leinad