简体   繁体   English

在文件中保存和加载 MemoryStream

[英]Save and load MemoryStream to/from a file

I am serializing an structure into a MemoryStream and I want to save and load the serialized structure.我正在将一个结构序列化为MemoryStream并且我想保存和加载序列化的结构。

So, How to Save a MemoryStream into a file and also load it back from file?那么,如何将MemoryStream保存到文件中并从文件中加载回来?

You may use MemoryStream.WriteTo or Stream.CopyTo (supported in framework version 4.5.2, 4.5.1, 4.5, 4) methods to write content of memory stream to another stream.您可以使用MemoryStream.WriteToStream.CopyTo (框架版本Stream.CopyTo支持)方法将内存流的内容写入另一个流。

memoryStream.WriteTo(fileStream);

Update:更新:

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

Assuming that MemoryStream name is ms .假设 MemoryStream 名称是ms

This code writes down MemoryStream to a file:此代码将 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();
}

and this reads a file to a MemoryStream :并将文件读取到 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);
}

In .Net Framework 4+, You can simply copy FileStream to MemoryStream and reverse as simple as this:在 .Net Framework 4+ 中,您可以简单地将 FileStream 复制到 MemoryStream 并像这样简单地反向:

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

And the Reverse (MemoryStream to FileStream):反过来(MemoryStream 到 FileStream):

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

The stream should really by disposed of even if there's an exception (quite likely on file I/O) - using clauses are my favourite approach for this, so for writing your MemoryStream, you can use:即使有异常(很可能在文件 I/O 上),流也应该真的被处理掉 - using 子句是我最喜欢的方法,所以为了编写你的 MemoryStream,你可以使用:

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

And for reading it back:并阅读它:

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

If the files are large, then it's worth noting that the reading operation will use twice as much memory as the total file size .如果文件很大,那么值得注意的是,读取操作将使用两倍于总文件大小的内存 One solution to that is to create the MemoryStream from the byte array - the following code assumes you won't then write to that stream.对此的一种解决方案是从字节数组创建 MemoryStream - 以下代码假定您随后不会写入该流。

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

My research (below) shows that the internal buffer is the same byte array as you pass it, so it should save memory.我的研究(如下)表明内部缓冲区与您传递的字节数组相同,因此它应该节省内存。

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

For anyone looking for the short versions:对于任何寻找简短版本的人:

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

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

The combined answer for writing to a file can be;写入文件的组合答案可以是;

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

Save into a file保存到文件中

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

Load from a file从文件加载

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

where在哪里

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

Originally the implementation of this class has been posted here原来这个类的实现已经贴在这里了

and

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

For loading a file, I like this a lot better对于加载文件,我更喜欢这个

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

I use a Panel Control to add a image or even stream video, but you can save the image on SQL Server as Image or MySQL as largeblob .我使用面板控件添加图像甚至流视频,但您可以将 SQL Server 上的图像另存为Image或将 MySQL 保存为largeblob This code works for me a lot.这段代码对我很有用。 Check it out.一探究竟。

Here you save the image在这里你保存图像

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

And here you can load, but I used a PictureBox Control.在这里你可以加载,但我使用了一个图片框控件。

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

Hope helps.希望有所帮助。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;

namespace ImageWriterUtil
{
    public class ImageWaterMarkBuilder
    {
        //private ImageWaterMarkBuilder()
        //{
        //}
        Stream imageStream;
        string watermarkText = "©8Bytes.Technology";
        Font font = new System.Drawing.Font("Brush Script MT", 30, FontStyle.Bold, GraphicsUnit.Pixel);
        Brush brush = new SolidBrush(Color.Black);
        Point position;
        public ImageWaterMarkBuilder AddStream(Stream imageStream)
        {
            this.imageStream = imageStream;
            return this;
        }
        public ImageWaterMarkBuilder AddWaterMark(string watermarkText)
        {
            this.watermarkText = watermarkText;
            return this;
        }
        public ImageWaterMarkBuilder AddFont(Font font)
        {
            this.font = font;
            return this;
        }

        public ImageWaterMarkBuilder AddFontColour(Color color)
        {
            this.brush = new SolidBrush(color);
            return this;
        }
        public ImageWaterMarkBuilder AddPosition(Point position)
        {
            this.position = position;
            return this;
        }

        public void CompileAndSave(string filePath)
        {

            //Read the File into a Bitmap.
            using (Bitmap bmp = new Bitmap(this.imageStream, false))
            {
                using (Graphics grp = Graphics.FromImage(bmp))
                {


                    //Determine the size of the Watermark text.
                    SizeF textSize = new SizeF();
                    textSize = grp.MeasureString(watermarkText, font);

                    //Position the text and draw it on the image.
                    if (position == null)
                        position = new Point((bmp.Width - ((int)textSize.Width + 10)), (bmp.Height - ((int)textSize.Height + 10)));
                    grp.DrawString(watermarkText, font, brush, position);

                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        //Save the Watermarked image to the MemoryStream.
                        bmp.Save(memoryStream, ImageFormat.Png);
                        memoryStream.Position = 0;
                       // string fileName = Path.GetFileNameWithoutExtension(filePath);
                        // outPuthFilePath = Path.Combine(Path.GetDirectoryName(filePath), fileName + "_outputh.png");
                        using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
                        {
                            byte[] bytes = new byte[memoryStream.Length];
                            memoryStream.Read(bytes, 0, (int)memoryStream.Length);
                            file.Write(bytes, 0, bytes.Length);
                            memoryStream.Close();
                        }
                    }
                }
            }

        }
    }
}

Usage :-用法 :-

ImageWaterMarkBuilder.AddStream(stream).AddWaterMark("").CompileAndSave(filePath);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM