Search code examples
c#serializationgrasshopper

Using BinaryFormatter to serialize a String[] variable within a class


I am trying to move the m_settings variable from the volatile to the persistent records. I have tried adding the [serializable] attribute to the class and sending the m_settings variable to a file stream using a BinaryFormatter but I got an error saying that the file cannot be written, access to the file is denied. What am I doing wrong?

[Serializable] 
public class SettingsComponent : GH_Component
{
    public SettingsComponent(): base("LoadSettings", "LoadSettings", "Loading ini", "Extra", "Silkworm") { }


    public override void CreateAttributes()
    {
        m_attributes = new SettingsComponentAttributes(this);
    }


    string m_settings_temp;
    string[] m_settings;
    public void ShowSettingsGui()
    {
        var dialog = new OpenFileDialog { Filter = "Data Sources (*.ini)|*.ini*|All Files|*.*" };
        if (dialog.ShowDialog() != DialogResult.OK) return;

        m_settings_temp = File.ReadAllText(dialog.FileName);
        m_settings = m_settings_temp.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
        ExpireSolution(true);
    }



    protected override void SolveInstance(IGH_DataAccess DA)
    {
        if (m_settings == null)
        {
           AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "You must declare some valid settings");
           return;
        }
        else
        {  
                    FileStream fs = new FileStream("DataFiletemp.dat", FileMode.Create);
                    BinaryFormatter formatter = new BinaryFormatter();
                    try
                    {
                        formatter.Serialize(fs, m_settings);
                    }
                    catch (SerializationException e)
                    {
                        Console.WriteLine("Failed to serialize. Reason: " + e.Message);
                        throw;
                    }
                    finally
                    {
                        fs.Close();
                    }

                   DA.SetDataList(0, m_settings);
        }  

    }

Solution

  • Arthur, if your m_settings object is not complex you can use project settings (application or user level). Here is sample code how you can save some project settings to app.config:

         [YourNamespace].Properties.Settings.Default["MyProperty"] = "Demo Value";
         [YourNamespace].Properties.Settings.Default.Save();
    

    And if you have the need for binary serialization you can use code like this: (serialized object and object of inheritance must be marked as serializable)

        /// <summary>
        /// Serializes object to file
        /// </summary>
        /// <param name="data"></param>
        /// <param name="FilePath"></param>
        public static void SerializeMyObject(object data, string FilePath)
        {
            System.IO.Stream stream = null;
            try
            {
                stream = System.IO.File.Open(FilePath, System.IO.FileMode.Create);
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
                new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                bformatter.Serialize(stream, data);
                stream.Close();
                stream.Dispose();
            }
            catch (Exception ex)
            {
                try
                {
                    stream.Close();
                    stream.Dispose();
                }
                catch (Exception)
                {
                }
                throw new Exception(ex.Message);
            }
        }