简体   繁体   中英

How to convert Memory Stream to System.Data.Linq.Binary?

I just need to do the reverse conversion as exposed in this question .

I have a MemoryStream and want to store it in a System.Data.Linq Binary field of my SQL CE database (FYI I'm using EF code first).

The MemoryStream is actually a XML, which is larger than the max size of a String field, so I found no other way than storing it in a Binary (suggestions on this subject REALLY appreciated).

My code (adapted)

   private Stream _userLayout;
   _userLayout = new MemoryStream();
   DXGridControl_Table.SaveLayoutToStream(_userLayout);
   MyDatabse.SomeTable.SomeBinaryField = _userLayout.????

MemorySteam class has ToArray() method:

MemoryStream.ToArray Method :

Writes the stream contents to a byte array, regardless of the Position property.

This method returns a copy of the contents of the MemoryStream as a byte array. If the current instance was constructed on a provided byte array, a copy of the section of the array to which this instance has access is returned. See the MemoryStream constructor for details.

This method works when the MemoryStream is closed.

With byte[] you can easily get Binary instance, because Byte[] to Binary implicit conversion is available:

MyDatabse.SomeTable.SomeBinaryField = (Binary) _userLayout.ToArray();

First there is

        byte[] buffer = new byte[LENGTH];
        MemoryStream memoryStream  = new MemoryStream(buffer);

In your example you can use

        DXGridControl_Table.SaveLayoutToStream(_userLayout);
        byte[] doSomethingwithyourData = _userLayout.GetBuffer();
        var length = _userLayout.Length;

With that information you can write the binary data to whatever.

Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method; however, ToArray creates a copy of the data in memory.

Or

Binary binary = new Binary(_userLayout.ToArray());

Like in the other answer said, there is an implicit conversion on binary:

public static implicit operator Binary(byte[] value) {
    return new Binary(value); 
}

You requested examples. A little example about the usage:

namespace Stackoverflow.Hannish.SaveLayout
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Windows.Forms;

    public partial class Form1 : Form
    {
        /// <summary>
        /// Here we store the layout data as a string. This is the data, that
        /// gets saved to disk / database / etc.
        /// </summary>
        private string layoutdata = string.Empty;

        public Form1()
        {
            this.InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Just some FooBar data.
            var data = new List<DataValue>
                           {
                               new DataValue { Id = 1, Name = "Xyz", IsCool = true }, 
                               new DataValue { Id = 2, Name = "Abc", IsCool = false }
                           };

            this.gridControl1.DataSource = data;
        }

        private void bnLoadLayout_Click(object sender, EventArgs e)
        {
            using (var stream = new MemoryStream())
            {
                var strdata = Encoding.Default.GetBytes(this.layoutdata);
                stream.Write(strdata, 0, strdata.Length);
                stream.Seek(0, SeekOrigin.Begin);
                this.gridView1.RestoreLayoutFromStream(stream);
            }
        }

        private void bnSaveLayout_Click(object sender, EventArgs e)
        {
            using (var stream = new MemoryStream())
            {
                this.gridView1.SaveLayoutToStream(stream);
                this.layoutdata = Encoding.Default.GetString(stream.ToArray());
            }
        }
    }
}

And some byte to file magic:

    private void bnLoadBinLayout_Click(object sender, EventArgs e)
    {
        using (FileStream fstream = File.Open("Layoutdata.bin", FileMode.Open))
        {
            int length = (int)fstream.Length;
            byte[] buffer = new byte[length];
            fstream.Read(buffer, 0, length);

            var memstream = new MemoryStream(buffer);
            this.gridView1.RestoreLayoutFromStream(memstream);
        }
    }

    private void bnSaveBinLayout_Click(object sender, EventArgs e)
    {
        using (FileStream fstream = File.Create("Layoutdata.bin"))
        {
            var memstream = new MemoryStream();
            this.gridView1.SaveLayoutToStream(memstream);
            fstream.Write(memstream.GetBuffer(), 0, (int)memstream.Length);
        }
    }

... just as example. DevExpress GridView can save the layout itself with SaveLayoutToXml();

To your second question and your (possible) conceptual mistake of converting the data back and forth.

Save that funny DevExpress XML in a ntext data column.

ntext: Variable-length Unicode data with a maximum length of (2^30–2)/2 (536,870,911) characters. Storage size, in bytes, is two times the number of characters entered.

See SQL Server Compact 4.0 Data Types

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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