Saving to SD-Card is to slow with ToString convert

Hello,
i have to write double and float values ​​at each time together to a line in a textfile on sdcard.

But the saving process or the sum of the values in one line takes too long.
I believe that the ToString method takes too long to convert the values.
Is there a solution without using ToString, and still save line by line? For Example without saving a string but another format?


public void StoreResult(string filename)
        {
            string buffer = null;

            buffer = datetime.ToString("F1"); // float
            buffer += "\t" + deviceDat[6].i_value.ToString();    // integer
            buffer += "\t" + deviceDat[7].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[8].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[9].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[0x10].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[0x11].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[0x12].i_value.ToString();  // integer
            buffer += "\t" + d[0].d_value.ToString("F1");  // double
            buffer += "\t" + d[1].d_value.ToString("F1");  // double
            buffer += "\t" + d[2].d_value.ToString("F1");  // double
            buffer += "\t" + deviceDat[6].d_Fn.ToString("F1");  // double
            buffer += "\t" + deviceDat[0x13].d_UBat.ToString("F1");  // double

            if (_storage != null)
            {
                try
                {
                    string path = _storage.RootDirectory + @ "\" + filename + ".txt";
                    StreamWriter sw = new StreamWriter(path, true);
                    sw.WriteLine(buffer);
                    sw.Flush();
                    sw.Close();
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.Message);
                }
            }
        }

If I understood you correctly, you say it like that?


public void StoreResult(string filename)
        {
            string buffer = null;
            /*
            buffer = datetime.ToString("F1"); // float
            buffer += "\t" + deviceDat[6].i_value.ToString();    // integer
            buffer += "\t" + deviceDat[7].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[8].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[9].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[0x10].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[0x11].i_value.ToString();  // integer
            buffer += "\t" + deviceDat[0x12].i_value.ToString();  // integer
            buffer += "\t" + d[0].d_value.ToString("F1");  // double
            buffer += "\t" + d[1].d_value.ToString("F1");  // double
            buffer += "\t" + d[2].d_value.ToString("F1");  // double
            buffer += "\t" + deviceDat[6].d_Fn.ToString("F1");  // double
            buffer += "\t" + deviceDat[0x13].d_UBat.ToString("F1");  // double
            */
            if (_storage != null)
            {
                try
                {
                    string path = _storage.RootDirectory + @ "\" + filename + ".txt";
                    StreamWriter sw = new StreamWriter(path, true);
                    sw.Write(datetime);
                    sw.Write('\t');
                    sw.Write(deviceDat[6].i_value.);
                    sw.Write('\t');
                    sw.Write(deviceDat[7].i_value);
                    // etc.
                    sw.Flush();
                    sw.Close();
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.Message);
                }
            }
        }

I’m not sure if this is of any help or faster. But if the format of the data is not that important. I use an object with the [Serializable()] annotation to store the information and then write to the SD card using:


            string fname = charactersPath + @ "\" + lp.ToString() + ".bin";
            byte[] rawCharacter = Reflection.Serialize(characters[lp], typeof(Character));
            try
            {
                storageDev.WriteFile(fname, rawCharacter);
                storageDev.Volume.FlushAll();
            }
            catch (Exception e)
            {
                ....
            }

@ andre.m The only downside is its only Deserializeable by the micro framework, not the normal one.


        Character LoadCharacter(int lp)
        {
            string fname = charactersPath + @ "\" + lp.ToString() + ".bin";
            Character newCharacter = new Character();
            try
            {
                byte[] rawCharacter = storageDev.ReadFile(fname);
                newCharacter = (Character)Reflection.Deserialize(rawCharacter, typeof(Character));
            }
            catch (Exception e)
            {
                ....
            }
            return newCharacter;
        }

@ andre.m Oh, ok. I will report on Friday whether saving now runs faster. But it looks much better and more logical. Thanks.

in .NET Strings can not be extended in length. This is why the whole string needs to be re allocated on every + operation.
So you should consider using StringBuilder to build strings.
Internally StringBuilder uses a char array which gets extended if needed.
You also can reserve capacity in advance by choosing the correct constructor (if you know the final length more or less exact).

So this might look like this:

var sb = new StringBuilder(20);
sb.Append("Hello");
sb.Append(' ');
sb.Append("World");
var str = sb.ToString();