Estoy serializando una estructura en un MemoryStream
y quiero guardar y cargar la estructura serializada.Guarde y cargue MemoryStream a/desde un archivo
Entonces, ¿cómo guardar un MemoryStream
en un archivo y también cargarlo desde el archivo?
Estoy serializando una estructura en un MemoryStream
y quiero guardar y cargar la estructura serializada.Guarde y cargue MemoryStream a/desde un archivo
Entonces, ¿cómo guardar un MemoryStream
en un archivo y también cargarlo desde el archivo?
Puede usar los métodos MemoryStream.WriteTo
o Stream.CopyTo
(admitidos en el marco de trabajo versión 4.5.2, 4.5.1, 4.5, 4) para escribir el contenido de la secuencia de la memoria en otra secuencia.
memoryStream.WriteTo(fileStream);
Actualización:
fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);
memoryStream.CopyTo no parece funcionar para mí, mientras que WriteTo lo hizo. Creo que fue porque mi memoryStream.Position no era 0 –
Sí, eso es correcto. La diferencia entre ellos es que CopyTo copia desde cualquier posición actual en lugar de desde el principio como lo hace WriteTo. – AnorZaken
Agregar ['[archivo | memoria] Stream.Seek (0, SeekOrigin.Begin);'] (https://msdn.microsoft.com/en-us/library/system.io.stream.seek (v = vs .110) .aspx) antes de que 'CopyTo' establezca la posición actual en 0, de modo que 'CopyTo' copiará la secuencia completa. –
Suponiendo que el nombre MemoryStream es ms
.
Este código escribe MemoryStream a un archivo:
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();
}
y esto se lee un archivo a un 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);
}
En .Net Framework 4+, puede simplemente copiar FileStream a MemoryStream y revertir tan simple como esto:
MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read))
file.CopyTo(ms);
y de marcha atrás (MemoryStream a FileStream):
using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
ms.CopyTo(file);
¿Puedo preguntar por qué utiliza FileMode.Create en la muestra de lectura frente a FileMode.Open? – Philter
En el primer bloque de código, en lugar de copiar manualmente la secuencia de memoria a la matriz, puede usar la función incorporada 'ms.ToArray()'. – Gman
Es importante establecer ms.Position = 0; de lo contrario, la matriz de bytes (y el archivo) contendrá todos los ceros. –
La respuesta combinada para escribir en un archivo puede ser;
MemoryStream ms = new MemoryStream();
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();
La corriente debe realmente por dispuesta incluso si hay una excepción (muy probablemente en el archivo de E/S) - el uso de cláusulas son mi método favorito para esto, así que para escribir su MemoryStream, puede utilizar:
using (FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write)) {
memoryStream.WriteTo(file);
}
y para leer de nuevo:
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);
}
Si los archivos son grandes, entonces vale la pena señalar que la operación de lectura utilizará el doble de memoria como t El tamaño total del archivo. Una solución para eso es crear el MemoryStream desde la matriz de bytes; el siguiente código asume que no escribirá en esa secuencia.
MemoryStream ms = new MemoryStream(bytes, writable: false);
Mi investigación (a continuación) muestra que el búfer interno es el mismo conjunto de bytes a medida que lo pasa, por lo que debería ahorrar memoria.
byte[] testData = new byte[] { 104, 105, 121, 97 };
var ms = new MemoryStream(testData, 0, 4, false, true);
Assert.AreSame(testData, ms.GetBuffer());
mejor respuesta aquí –
Para cargar un archivo, me gusta esto mucho mejor
MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
fs.CopyTo(ms);
}
Si el archivo se abre en Microsoft Word, ¿hay alguna manera de crear una secuencia de memoria desde ese archivo? Estoy recibiendo un error '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, entonces no puede hacerlo. Solo cierre el archivo en Word. – Kristopher
Guardar en un archivo
Car car = new Car();
car.Name = "Some fancy car";
MemoryStream stream = Serializer.SerializeToStream(car);
System.IO.File.WriteAllBytes(fileName, stream.ToArray());
carga de un archivo de
using (var stream = new MemoryStream(System.IO.File.ReadAllBytes(fileName)))
{
Car car = (Car)Serializer.DeserializeFromStream(stream);
}
donde
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, la implementación de esta clase ha sido publicado here
y
[Serializable]
public class Car
{
public string Name;
}
utilizo un panel de control para agregar una imagen o incluso flujo de vídeo, pero puede guardar la imagen en SQL Server como Imagen o MySQL como largeblob. Este código funciona para mí mucho. Echale un vistazo.
Aquí se guarda la imagen
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();
Y aquí se puede cargar, pero utilizó un control PictureBox.
MemoryStream ms = new MemoryStream(picarr);
ms.Seek(0, SeekOrigin.Begin);
fotos.pictureBox1.Image = System.Drawing.Image.FromStream(ms);
Hope helps.
Para el que busque las versiones cortas:
var memoryStream = new MemoryStream(File.ReadAllBytes("1.dat"));
File.WriteAllBytes("1.dat", memoryStream.ToArray());
Si necesita guardar en un archivo, ¿por qué estás usando un 'MemoryStream'? – Oded
@Oded ¿Qué debo usar? ¿Puedes darme un ejemplo? –