Salvar e carregar o MemoryStream de / para um arquivo

Eu estou serializando uma estrutura em um MemoryStream e quero salvar e carregar a estrutura serializada.

Então, como salvar um MemoryStream em um arquivo e também carregá-lo de volta do arquivo?

Você pode usar os Stream.CopyTo MemoryStream.WriteTo ou Stream.CopyTo (com suporte na versão 4.5.2, 4.5.1, 4.5, 4) para gravar o conteúdo do stream de memory em outro stream.

 memoryStream.WriteTo(fileStream); 

Atualizar:

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

Supondo que o nome do MemoryStream seja ms .

Este código anota o MemoryStream em um arquivo:

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

e isso lê um arquivo para um 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); } 

No .Net Framework 4+, você pode simplesmente copiar o FileStream para o MemoryStream e reverter de maneira simples como esta:

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

E o reverso (MemoryStream to FileStream):

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

O stream deve ser descartado mesmo se houver uma exceção (muito provavelmente no arquivo I / O) – usar cláusulas é a minha abordagem favorita para isso, então, para escrever seu MemoryStream, você pode usar:

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

E para ler de volta:

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

Se os arquivos forem grandes, vale a pena observar que a operação de leitura usará o dobro de memory do tamanho total do arquivo . Uma solução para isso é criar o MemoryStream a partir da matriz de bytes – o código a seguir assume que você não gravará nesse stream.

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

Minha pesquisa (abaixo) mostra que o buffer interno é o mesmo array de bytes que você passa, então ele deve economizar memory.

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

Para quem procura as versões curtas:

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

A resposta combinada para gravar em um arquivo pode ser;

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

Para carregar um arquivo, eu gosto muito disso

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

Salvar em um arquivo

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

Carregar de um arquivo

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

Onde

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

Originalmente, a implementação desta class foi publicada aqui

e

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

Eu uso um painel de controle para adicionar uma imagem ou mesmo streaming de vídeo, mas você pode salvar a imagem no SQL Server como imagem ou MySQL como largeblob . Esse código funciona muito para mim. Confira.

Aqui você salva a imagem

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

E aqui você pode carregar, mas eu usei um controle PictureBox.

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

Esperança ajuda.