Si necesita guardar en un archivo, ¿por qué está utilizando un MemoryStream?
Oded
@Oded ¿Qué debo usar? ¿Puedes darme un ejemplo?
Mahdi Ghiasi
Respuestas:
365
Puede usar métodos ( MemoryStream.WriteToo Stream.CopyTocompatibles con la versión 4.5.2, 4.5.1, 4.5, 4) para escribir el contenido de la secuencia de memoria en otra secuencia.
memoryStream.CopyTo no parecía funcionar para mí, mientras que WriteTo sí. Creo que tal vez fue porque mi memoria Stream.Position no era 0
Mark Adamson
10
Si, eso es correcto. La diferencia entre ellos es que CopyTo copia desde cualquier posición actual en lugar de siempre desde el principio como lo hace WriteTo.
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();}
y esto lee un archivo en un 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);}
En .Net Framework 4+, simplemente puede copiar FileStream a MemoryStream y revertirlo de la siguiente manera:
MemoryStream ms =newMemoryStream();
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read))
file.CopyTo(ms);
Y el reverso (MemoryStream a FileStream):
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write))
ms.CopyTo(file);
¿Puedo preguntar por qué usas FileMode.Create en la muestra de lectura vs FileMode.Open?
Philter
66
En el primer bloque de código, en lugar de copiar manualmente el flujo de memoria a la matriz, puede usar la ms.ToArray()función incorporada.
Gman
55
Es importante establecer ms.Position = 0; de lo contrario, la matriz de bytes (y el archivo) contendrán todos los ceros.
Gregory Khrapunovich
1
@ Fernando68 la construcción using (...){ }tiene exactamente el mismo efecto.
Fabricio Araujo
2
Solo como una advertencia a los demás 'usando (FileStream' y 'ms.CopyTo (file)' establece la posición al final del archivo y luego debe restablecer el flujo de memoria.
Rebecca
64
La transmisión realmente debería eliminarse incluso si hay una excepción (muy probablemente en E / S de archivo): el uso de cláusulas es mi enfoque favorito para esto, por lo que para escribir su MemoryStream, puede usar:
using (FileStream file =newFileStream("file.bin",FileMode.Create,FileAccess.Write)){
memoryStream.WriteTo(file);}
Y para leerlo de nuevo:
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);}
Si los archivos son grandes, vale la pena señalar que la operación de lectura usará el doble de memoria que el tamaño total del archivo . Una solución para eso es crear MemoryStream a partir de la matriz de bytes: el siguiente código supone que no escribirás en esa secuencia.
MemoryStream ms =newMemoryStream(bytes, writable:false);
Mi investigación (a continuación) muestra que el búfer interno es el mismo conjunto de bytes que lo pasa, por lo que debería ahorrar memoria.
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());
Cargar desde un archivo
using (var stream =newMemoryStream(System.IO.File.ReadAllBytes(fileName))){Car car =(Car)Serializer.DeserializeFromStream(stream);}
dónde
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, la implementación de esta clase se publicó aquí
Si el archivo se abre en Microsoft Word, ¿hay alguna forma de crear una secuencia de memoria a partir de ese archivo? Recibo un error 'el archivo se abre por otro proceso'
FrenkyB
@FrenkyB También me encuentro con esto mucho. Si tiene el archivo abierto en Word o en alguna otra aplicación, no podrá hacerlo. Simplemente cierre el archivo en Word.
Kristopher
@FrenkyB ¿Puedes hacer un File.Copy? He encontrado que funciona, luego leí ese archivo en una secuencia y eliminé el nuevo archivo ... horrible, pero parece funcionar.
ridecar2
3
Utilizo un Control de panel para agregar una imagen o incluso transmitir video, pero puede guardar la imagen en SQL Server como Imagen o MySQL como bloque grande . Este código me funciona mucho. Echale un vistazo.
Aquí guardas la imagen
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();
Y aquí puedes cargar, pero utilicé un PictureBox Control.
MemoryStream ms =newMemoryStream(picarr);
ms.Seek(0,SeekOrigin.Begin);
fotos.pictureBox1.Image=System.Drawing.Image.FromStream(ms);
MemoryStream
?Respuestas:
Puede usar métodos (
MemoryStream.WriteTo
oStream.CopyTo
compatibles con la versión 4.5.2, 4.5.1, 4.5, 4) para escribir el contenido de la secuencia de memoria en otra secuencia.Actualizar:
fuente
[file|memory]Stream.Seek(0, SeekOrigin.Begin);
antesCopyTo
establecerá la posición actual en 0, por lo queCopyTo
copiará la secuencia completa.Suponiendo que el nombre MemoryStream es
ms
.Este código escribe MemoryStream en un archivo:
y esto lee un archivo en un MemoryStream:
En .Net Framework 4+, simplemente puede copiar FileStream a MemoryStream y revertirlo de la siguiente manera:
Y el reverso (MemoryStream a FileStream):
fuente
ms.ToArray()
función incorporada.using (...){ }
tiene exactamente el mismo efecto.La transmisión realmente debería eliminarse incluso si hay una excepción (muy probablemente en E / S de archivo): el uso de cláusulas es mi enfoque favorito para esto, por lo que para escribir su MemoryStream, puede usar:
Y para leerlo de nuevo:
Si los archivos son grandes, vale la pena señalar que la operación de lectura usará el doble de memoria que el tamaño total del archivo . Una solución para eso es crear MemoryStream a partir de la matriz de bytes: el siguiente código supone que no escribirás en esa secuencia.
Mi investigación (a continuación) muestra que el búfer interno es el mismo conjunto de bytes que lo pasa, por lo que debería ahorrar memoria.
fuente
Para cualquiera que busque las versiones cortas:
fuente
La respuesta combinada para escribir en un archivo puede ser;
fuente
Guardar en un archivo
Cargar desde un archivo
dónde
y
fuente
Para cargar un archivo, me gusta mucho más
fuente
Utilizo un Control de panel para agregar una imagen o incluso transmitir video, pero puede guardar la imagen en SQL Server como Imagen o MySQL como bloque grande . Este código me funciona mucho. Echale un vistazo.
Aquí guardas la imagen
Y aquí puedes cargar, pero utilicé un PictureBox Control.
La esperanza ayuda.
fuente
Uso: -
fuente