System.IndexOutOfRangeException, SD-Card, G120

Hi, When I Run the following code I get an System.IndexOutOfRangeException.

It always happens about line 40 in the log. I’m just trying to read the line count till about line 100. Then trim it down to about 60. By writing line by line to temporary new file, deleting the old and then renaming the new.


public static int LineCount(string file)
        {
            if (Detect.SD_Card() & File.Exists(file))
            {
                lock (CardLock)
                {
                    using (StreamReader r = new StreamReader(file))
                    {
                        int i = 0;
                        while (r.ReadLine() != null) { i++; }
                        return i;
                    }
                }
            }
            return 0;
        }

Here is how I read a specific line. Thought I’d add it in case someone can improve on it.


public static string ReadLine(string file, int line)
        {
            if (Detect.SD_Card() & File.Exists(file))
            {
                lock (CardLock)
                {
                    using (StreamReader r = new StreamReader(file))
                    {
                        int i = 0;
                        while (r.ReadLine() != null & i != line) 
                        { 
                            i++; 
                        }
                        if (i == line)
                        {
                            return r.ReadLine();
                        }
                    }
                }
            }
            return "EOF";
        }

Thanks in advance.

Attempting to write with buffer of 22
#### Exception System.IndexOutOfRangeException - 0xa9000000 (1) ####
#### Message:
#### System.IO.StreamReader::Peek [IP: 001c] ####
#### System.IO.StreamReader::ReadLine [IP: 005e] ####
#### G120.Tools.FileManagement.FileManager::LineCount [IP: 0030] ####
#### G120.Tools.FileManagement.Log::LogTrunc [IP: 0014] ####
#### G120.Tools.FileManagement.Log::Print [IP: 0153] ####
#### G120.Program::Main [IP: 0054] ####

@ xrstokes - Can you post a complete example along with a sample file contents so we can try it here?

I tried to re-write a simpler version of it cause it’s a rather large solution. Here it is.

It still fails to count the lines but with this smaller version fails at line 98.
Here is the error. It’s also a different error? But I only moved the code around to make it easier to read?

Attempting to write with buffer of 19
GC: 15msec 543348 bytes used, 6796320 bytes available
Type 0F (STRING ): 636 bytes
Type 11 (CLASS ): 10968 bytes
Type 12 (VALUETYPE ): 1428 bytes
Type 13 (SZARRAY ): 4956 bytes
Type 01 (BOOLEAN ): 24 bytes
Type 03 (U1 ): 1272 bytes
Type 04 (CHAR ): 516 bytes
Type 07 (I4 ): 36 bytes
Type 11 (CLASS ): 3036 bytes
Type 12 (VALUETYPE ): 72 bytes
Type 15 (FREEBLOCK ): 6796320 bytes
Type 16 (CACHEDBLOCK ): 264 bytes
Type 17 (ASSEMBLY ): 40476 bytes
Type 18 (WEAKCLASS ): 48 bytes
Type 19 (REFLECTION ): 168 bytes
Type 1B (DELEGATE_HEAD ): 360 bytes
Type 1D (OBJECT_TO_EVENT ): 312 bytes
Type 1E (BINARY_BLOB_HEAD ): 475188 bytes
Type 1F (THREAD ): 1152 bytes
Type 20 (SUBTHREAD ): 144 bytes
Type 21 (STACK_FRAME ): 672 bytes
Type 27 (FINALIZER_HEAD ): 504 bytes
Type 31 (IO_PORT ): 468 bytes
Type 34 (APPDOMAIN_HEAD ): 72 bytes
Type 36 (APPDOMAIN_ASSEMBLY ): 5532 bytes
#### Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (1) ####
#### Message:
#### Microsoft.SPOT.IO.NativeFileStream::GetLength [IP: 0000] ####
#### System.IO.FileStream::get_Length [IP: 001b] ####
#### System.IO.StreamReader::ReadLine [IP: 0076] ####
#### G120.Program::LineCount [IP: 0015] ####
#### G120.Program::Main [IP: 0075] ####
A first chance exception of type ‘System.ObjectDisposedException’ occurred in Microsoft.SPOT.IO.dll
An unhandled exception of type ‘System.ObjectDisposedException’ occurred in Microsoft.SPOT.IO.dll


public static void Main()
        {
            Sally.Startup();

            Debug.Print(SAL.RTC.GetAll().ToString());

            Log.Print("Restarting, Program Number = " + Program_No.ToString(), 1); 

            SAL.LEDs.Show(0);

            InputPort ldro = new InputPort(GHI.Pins.G120.P2_10, true, Port.ResistorMode.Disabled);

            int x = 0;

            while (true)
            {
                if (!ldro.Read())
                {
                    x++;

                    Debug.Print("testing line " + x);

                    Writer("testing line " + x + " \r\n ", @ "\SD\Logs", @ "\ErrorLog.txt");

                    Debug.Print("line count = " + LineCount(@ "\SD\Logs\ErrorLog.txt"));
                }
            }

            //Launcher();

            Thread.Sleep(Timeout.Infinite); 
        }

        public static void Writer(string msg, string path, string file, bool append = true)
        {
                int bufferSize = msg.Length;

                Debug.Print("Attempting to write with buffer of " + bufferSize.ToString());

                //Create
                if (!append || !File.Exists(path + file))
                {
                    try
                    {
                        if (File.Exists(path + file))
                        {
                            using (var writestream = new FileStream(path + file, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, bufferSize))
                            {
                                StreamWriter SW = new StreamWriter(writestream);
                                SW.Write(msg);
                                SW.Flush();
                                SW.Close();
                            }
                        }
                        else
                        {
                            if (!Directory.Exists(path))
                            {
                                Directory.CreateDirectory(path);
                            }

                            using (var writestream = new FileStream(path + file, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, bufferSize))
                            {
                                StreamWriter SW = new StreamWriter(writestream);
                                SW.Write(msg);
                                SW.Flush();
                                SW.Close();
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.Print("SD_Writer Failed to Create" + e.Message);
                    }
                }

                //Append
                else
                {
                    try
                    {
                        if (File.Exists(path + file))
                        {
                            using (var writestream = new FileStream(path + file, FileMode.Append))
                            {
                                StreamWriter SW = new StreamWriter(writestream);
                                SW.Write(msg);
                                SW.Flush();
                                SW.Close();
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.Print("SD_Writer Failed to Append" + e.Message);
                    }
                }

                try
                {
                    VolumeInfo.GetVolumes()[0].FlushAll();
                }
                catch
                {
                    Debug.Print("failed to flush");
                }
            
        }

        public static int LineCount(string file)
        {
            using (StreamReader r = new StreamReader(file))
            {
                int i = 0;
                while (r.ReadLine() != null) { i++; }
                return i;
            }
        }

@ xrstokes - The code you posted doesn’t contain the source for Sally.Startup(), SAL.RTC.GetAll(), or SAL.LEDs.Show(0). Can you post a working version that doesn’t use those? Are you also running the latest firmware?

Sorry, Try this.


using System;
using System.IO;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;

using GHI.Processor;
using GHI.IO.Storage;

using G120.SAL.Eth;

using G120.Tools.FileManagement;

namespace G120
{
    public class Program
    {
        public static String Software_Version = "4.3.2.00.00";

        public static String Hardware_Version = "MP_001";

        public static int Program_No;

        public static void Main()
        {
            // Card inserted? Lets try mounting.
            SDCard SD = new SDCard();

            // Mount the file system        
            SD.Mount();
            
            int x = 0;

                // Write 200 lines to the SD Card.

                while (x < 200)
                {
                    Writer("testing line " + x + " \r\n ", @ "\SD\Logs", @ "\ErrorLog.txt");

                    x++;
                }

                // Try to count the lines.

                Debug.Print("line count = " + LineCount(@ "\SD\Logs\ErrorLog.txt"));

            //Launcher();

            Thread.Sleep(Timeout.Infinite); 
        }

        public static void Writer(string msg, string path, string file, bool append = true)
        {
                int bufferSize = msg.Length;

                Debug.Print("Attempting to write with buffer of " + bufferSize.ToString());

                //Create
                if (!append || !File.Exists(path + file))
                {
                    try
                    {
                        if (File.Exists(path + file))
                        {
                            using (var writestream = new FileStream(path + file, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, bufferSize))
                            {
                                StreamWriter SW = new StreamWriter(writestream);
                                SW.Write(msg);
                                SW.Flush();
                                SW.Close();
                            }
                        }
                        else
                        {
                            if (!Directory.Exists(path))
                            {
                                Directory.CreateDirectory(path);
                            }

                            using (var writestream = new FileStream(path + file, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, bufferSize))
                            {
                                StreamWriter SW = new StreamWriter(writestream);
                                SW.Write(msg);
                                SW.Flush();
                                SW.Close();
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.Print("SD_Writer Failed to Create" + e.Message);
                    }
                }

                //Append
                else
                {
                    try
                    {
                        if (File.Exists(path + file))
                        {
                            using (var writestream = new FileStream(path + file, FileMode.Append))
                            {
                                StreamWriter SW = new StreamWriter(writestream);
                                SW.Write(msg);
                                SW.Flush();
                                SW.Close();
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.Print("SD_Writer Failed to Append" + e.Message);
                    }
                }

                try
                {
                    VolumeInfo.GetVolumes()[0].FlushAll();
                }
                catch
                {
                    Debug.Print("failed to flush");
                }
            
        }

        public static int LineCount(string file)
        {
            using (StreamReader r = new StreamReader(file))
            {
                int i = 0;
                while (r.ReadLine() != null) { i++; }
                return i;
            }
        }
    }
}

@ xrstokes - I was able to reproduce it. Unfortunately, it is a known issue in NETMF itself. It has already been fixed for 4.4.

See:

https://www.ghielectronics.com/community/forum/topic?id=13700
https://www.ghielectronics.com/community/forum/topic?id=8577