Main Site Documentation

System.IO.IOException when reading from SD Card - Fez Cerberus


#1

Hello, I keep getting the error above when trying to read from a text file located on my SD Card, for some reason it allows me to continue but it’s still annoying, I’m guessing it has something to do with either closing the Filestream or Disposing of the SDCard object, I’ve read many posts on how to use the SDCard object but all this has done is confuse me more, below is my code if anyone can spot any obvious mistakes.

public static string ReadLine(string fileName, int lineNumber)
        {
            var line = "";
            var sd = new SDCard();
            sd.Mount();

            while (!sd.Mounted)
            {

            }

            var fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);

            var lineNo = 0;
            using (var sr = new StreamReader(fs))
            {
                while (sr.Peek() >= 0)
                {
                    lineNo++;
                    line = sr.ReadLine();

                    if (lineNo == lineNumber)
                    {
                        goto DONE;
                    }
                }
            }

            DONE:

            fs.Close();
            sd.Unmount();
            sd.Dispose();

            return "";
        }

#2

@ chillydk147 -

What line do you get this exception?


#3

@ Dat - It doesn’t break inside this method, only when I return to code which called the method??


#4

This is another message I see when pressing the break button on the error popup, no idea what it means


#5

@ Andre - I’ve added the “Microsoft.SPOT.IO” assembly and included it as a using namespace but I still get the same cryptic message??


#6

@ chillydk147 -

Your problem can be:

  • The SD need to be reformat. I know it can work perfectly on PC but sometime need to be reformatted again.
  • The path can be wrong. Missing “\SD” or something else…
    and last thing to do
  • Try lower clock

I think the code below is a bit better to debug.

using System;
using System.IO;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;
using GHI.IO;
using GHI.IO.Storage;

namespace Cerb_SD_Tester
{
    public class Program
    {
        private static OutputPort _led = new OutputPort((Cpu.Pin)(2 * 16 + 4), true); // LED
        static InputPort button_ldr1 = new InputPort((Cpu.Pin)(2 * 16 + 2), false, Port.ResistorMode.PullUp); // Socket 4 - PC2 - pin 3       
        public static void Main()
        {
            
			// Part I -> Press button to InitSD card
            while (button_ldr1.Read() == true)
            {
                
                Thread.Sleep(500);
                _led.Write(true);
                Thread.Sleep(500);
                _led.Write(false);
                
                
            }           
            _led.Write(false);
            SDCard sdPS = new SDCard();
            // Mount the file system
            sdPS.Mount();
            VolumeInfo vol = VolumeInfo.GetVolumes()[0];
            if (vol.IsFormatted == false )
            {
                Debug.Print("Formating...!");
                vol.Format("FAT", 0);
                Debug.Print("Formatted!");
                _led.Write(true);
            }
            else
            {
                Debug.Print("Initialize OK....");
                Debug.Print("Label = " + vol.VolumeLabel);
                Debug.Print("Size = " + vol.TotalSize);
            }
			// Part II -> Press button to Write file
            while (button_ldr1.Read() == true)
            {

                Thread.Sleep(50);
                _led.Write(true);
                Thread.Sleep(50);
                _led.Write(false);
               

            }
            Debug.Print("Getting files and folders:");
            int i;
            if (vol.IsFormatted)
            {
                string rootDirectory =
                    VolumeInfo.GetVolumes()[0].RootDirectory;
                //// For explore
                string[] files = Directory.GetFiles(rootDirectory);
                string[] folders = Directory.GetDirectories(rootDirectory);

                Debug.Print("Files available on " + rootDirectory + ":");
                for ( i = 0; i < files.Length; i++)
                    Debug.Print(files[i]);

                Debug.Print("Folders available on " + rootDirectory + ":");
                for ( i = 0; i < folders.Length; i++)
                    Debug.Print(folders[i]);

                //Thread.Sleep(-1);
                const int BLOCK_SIZE = 1*1024 ;

                byte[] data = new byte[BLOCK_SIZE];
                FileStream stream;
				////// For Write
                stream = new FileStream(rootDirectory
                           + @ "\test.txt", FileMode.Create);               
                for (i = 0; i < BLOCK_SIZE; i++)
                {
                    data[i] = (byte)(i % 0xFF);
                }
                long time_start = DateTime.Now.Ticks;
				
                for (i = 0; i < 100; i++) // write 1M
                {
                    try
                    {
                        stream.Write(data, 0, BLOCK_SIZE);
                    }
                    catch
                    {
                        Debug.Print(" Error at i = " + i);
                    }                    
                    if (i % 10 == 0)
                    {
                     
                        Debug.Print("i== " + i);
                    }                     
                }
                long time_end = DateTime.Now.Ticks - time_start;
                Debug.Print("Write end =  " + time_end);               
                stream.Close();
                stream.Dispose();
                stream = null;

                ////// For read //////////////////////
                stream = new FileStream(rootDirectory
                           + @ "\test.txt", FileMode.Open);
				// Just try first block
                stream.Read(data, 0, BLOCK_SIZE);
                for (i = 0; i < BLOCK_SIZE; i++)
                {
                    if (data[i] != (byte)(i % 0xFF))
                    {
                        Debug.Print("=>>>>>>>>>>>>>>>>>>>>>>>>>>> Test Read failed!");
                        break;
                    }
                }
                stream.Dispose();
                stream.Close();
                stream = null;
                Debug.Print("Read OK!");
            }
            else
            {
                Debug.Print("Storage is not formatted. Format on PC with FAT32/FAT16 first.");
            }
 
            // Unmount
            sdPS.Unmount();
            _led.Write(true);
            Thread.Sleep(-1);
        }

    }
}

#7

@ Dat - Thanks for the code, the SD card is formatted as FAT32, the code hits the line " Test Read failed!", its strange because if I comment this block out and let it read my code it does indeed pull out the line I need, it’s just the error message which I don’t understand.

////// For read //////////////////////

var stream = new FileStream(fileName, FileMode.Open);
                
                // Just try first block
                stream.Read(data, 0, BLOCK_SIZE);
                for (short i = 0; i < BLOCK_SIZE; i++)
                {
                    if (data[i] != (byte)(i % 0xFF))
                    {
                        Debug.Print("=>>>>>>>>>>>>>>>>>>>>>>>>>>> Test Read failed!");
                        break;
                    }
                }

#8

[quote] the code hits the line " Test Read failed!",
[/quote]

Which code are you using? my code or yours?

If your code then you have to check the path - file name


#9

I can see that data is populated with 1024 bytes


#10

@ chillydk147 -

So what exactly problem do you have now?