Se você precisar salvar em um arquivo, por que está usando um MemoryStream?
Oded
@Oded O que devo usar? Você pode me dar um exemplo?
Mahdi Ghiasi
Respostas:
365
Você pode usar MemoryStream.WriteToou Stream.CopyTo(com suporte na versão 4.5.2, 4.5.1, 4.5, 4) do framework para gravar o conteúdo do fluxo de memória em outro fluxo.
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write)){byte[] bytes =newbyte[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 =newMemoryStream())
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read)){byte[] bytes =newbyte[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 da maneira mais simples possível:
MemoryStream ms =newMemoryStream();
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read))
file.CopyTo(ms);
E o reverso (MemoryStream para FileStream):
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write))
ms.CopyTo(file);
Posso perguntar por que você usa FileMode.Create no exemplo de leitura vs FileMode.Open?
Philter
6
No primeiro bloco de código, em vez de copiar manualmente o fluxo de memória para a matriz, você pode usar a ms.ToArray()função interna.
Gman
5
É importante definir ms.Position = 0, caso contrário, a matriz de bytes (e o arquivo) conterão todos os zeros.
Gregory Khrapunovich
1
@ Fernando68 a construção using (...){ }tem exatamente o mesmo efeito.
Fabricio Araujo
2
Apenas como um aviso para os outros 'using (FileStream' e 'ms.CopyTo (file)' definir a posição no final do arquivo e você precisará redefinir o fluxo de memória posteriormente.
Rebecca
63
O fluxo deve realmente ser descartado, mesmo que haja uma exceção (provavelmente no E / S do arquivo) - usar cláusulas é minha abordagem favorita para isso; portanto, para escrever seu MemoryStream, você pode usar:
using (FileStream file =newFileStream("file.bin",FileMode.Create,FileAccess.Write)){
memoryStream.WriteTo(file);}
E para ler de volta:
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read)){byte[] bytes =newbyte[file.Length];
file.Read(bytes,0,(int)file.Length);
ms.Write(bytes,0,(int)file.Length);}
Se os arquivos forem grandes, é importante notar que a operação de leitura usará o dobro da memória que o 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 fluxo.
MemoryStream ms =newMemoryStream(bytes, writable:false);
Minha pesquisa (abaixo) mostra que o buffer interno é a mesma matriz de bytes que você passa, portanto, ele deve economizar memória.
byte[] testData =newbyte[]{104,105,121,97};var ms =newMemoryStream(testData,0,4,false,true);Assert.AreSame(testData, ms.GetBuffer());
Car car =newCar();
car.Name="Some fancy car";MemoryStream stream =Serializer.SerializeToStream(car);System.IO.File.WriteAllBytes(fileName, stream.ToArray());
Carregar de um arquivo
using (var stream =newMemoryStream(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{publicclassSerializer{publicstaticMemoryStreamSerializeToStream(object o){MemoryStream stream =newMemoryStream();IFormatter formatter =newBinaryFormatter();
formatter.Serialize(stream, o);return stream;}publicstaticobjectDeserializeFromStream(MemoryStream stream){IFormatter formatter =newBinaryFormatter();
stream.Seek(0,SeekOrigin.Begin);object o = formatter.Deserialize(stream);return o;}}}
Originalmente, a implementação desta classe foi publicada aqui
Se o arquivo for aberto no Microsoft Word - existe uma maneira de criar um fluxo de memória a partir desse arquivo? Estou recebendo um erro 'o arquivo é aberto por outro processo'
FrenkyB
@FrenkyB Eu também encontro muito isso. Se você tiver o arquivo aberto no Word ou em algum outro aplicativo, não poderá fazê-lo. Apenas feche o arquivo no Word.
`` #
@FrenkyB Você pode fazer um File.Copy? Descobri que isso funcionava, depois li esse arquivo em um fluxo e excluí o novo arquivo ... horrível, mas parece funcionar.
ridecar2
3
Eu uso um Painel de Controle para adicionar uma imagem ou até transmitir vídeo, mas você pode salvar a imagem no SQL Server como Imagem ou MySQL como largeblob . Este código funciona muito para mim. Confira.
Aqui você salva a imagem
MemoryStream ms =newMemoryStream();Bitmap bmp =newBitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);// here you can change the Image formatbyte[]Pic_arr=newbyte[ms.Length];
ms.Position=0;
ms.Read(Pic_arr,0,Pic_arr.Length);
ms.Close();
E aqui você pode carregar, mas eu usei um PictureBox Control.
MemoryStream ms =newMemoryStream(picarr);
ms.Seek(0,SeekOrigin.Begin);
fotos.pictureBox1.Image=System.Drawing.Image.FromStream(ms);
MemoryStream
?Respostas:
Você pode usar
MemoryStream.WriteTo
ouStream.CopyTo
(com suporte na versão 4.5.2, 4.5.1, 4.5, 4) do framework para gravar o conteúdo do fluxo de memória em outro fluxo.Atualizar:
fonte
[file|memory]Stream.Seek(0, SeekOrigin.Begin);
antesCopyTo
definirá a posição atual como 0, paraCopyTo
copiar o fluxo completo.Supondo que o nome MemoryStream seja
ms
.Este código grava MemoryStream em um arquivo:
e isso lê um arquivo para um MemoryStream:
No .Net Framework 4+, você pode simplesmente copiar o FileStream para o MemoryStream e reverter da maneira mais simples possível:
E o reverso (MemoryStream para FileStream):
fonte
ms.ToArray()
função interna.using (...){ }
tem exatamente o mesmo efeito.O fluxo deve realmente ser descartado, mesmo que haja uma exceção (provavelmente no E / S do arquivo) - usar cláusulas é minha abordagem favorita para isso; portanto, para escrever seu MemoryStream, você pode usar:
E para ler de volta:
Se os arquivos forem grandes, é importante notar que a operação de leitura usará o dobro da memória que o 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 fluxo.
Minha pesquisa (abaixo) mostra que o buffer interno é a mesma matriz de bytes que você passa, portanto, ele deve economizar memória.
fonte
Para quem procura as versões curtas:
fonte
A resposta combinada para gravar em um arquivo pode ser;
fonte
Salvar em um arquivo
Carregar de um arquivo
Onde
e
fonte
Para carregar um arquivo, eu gosto muito mais disso
fonte
Eu uso um Painel de Controle para adicionar uma imagem ou até transmitir vídeo, mas você pode salvar a imagem no SQL Server como Imagem ou MySQL como largeblob . Este código funciona muito para mim. Confira.
Aqui você salva a imagem
E aqui você pode carregar, mas eu usei um PictureBox Control.
A esperança ajuda.
fonte
Uso: -
fonte