Author Topic: StreamReader Problem  (Read 22083 times)

0 Members and 1 Guest are viewing this topic.

wannabe

  • Guest
StreamReader Problem
« on: April 23, 2009, 09:42:33 AM »
This loop below is causing me a problem. It never seems that the StreamReader is returning a true for the EndOfStream property.

Code: [Select]
public Dictionary<int, string[]> createCoordsList(string separator) //This method separates the stream into coords/attributes for each block
        {
            StreamReader str;
            Dictionary<int, string[]> coordsList = new Dictionary<int, string[]>();
            int numOfLines = 0; //Assign the number of lines in the stream to this integer
            bool isError = false;
            using (StreamReader tempStream = new StreamReader(File.Open(path, FileMode.Open))) //Create a new stream using our parameter to quantify number of lines
            {
                string tempString = "";//Populate this string with the current line of the stream
                while (true)//This Loop is to determine only the number of lines in this stream
                {
                    try
                    {
                        bool endLines = tempStream.EndOfStream;
                        if (endLines)
                        {
                            isError = true;
                            break;
                        }
                        tempString = tempStream.ReadLine();//Assigned the string for the current line of the stream
                    }

                    catch
                    {
                        throw new System.Exception("There was a problem");
                       
                    }

                    if (tempString == null)
                    {
                        break;//The line was empty so we exit the loop
                    }

                    numOfLines++;//The line wasn't empty so we increment this integer
              }
            }

            if (isError)
            {
                return null;
            }

I'm sure it's a basic problem, but the solution is eluding me after a tenacious effort this morning.

Sorry for "noob" question.

wannabe

  • Guest
Re: StreamReader Problem
« Reply #1 on: April 23, 2009, 10:11:29 AM »
Actually, ignore this for now, please. I'll update accordingly soon.

Cheers.

wannabe

  • Guest
Re: StreamReader Problem
« Reply #2 on: April 23, 2009, 11:06:31 AM »

Ok, here's the full extent of my code. It's designed to read in the coordinates from a txt file, whose values are separated by spaces, and take each individual string from a line read in from a stream to populate a string array. An array for each line will be used to populate a dictionary whose values I just want to spit out to the command line at this point.

However, things aren't going too great. If anyone can spot the errors, please be as brutal as necessary.

Cheers.

Code: [Select]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using System.IO;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;

///Notes:
///1. Ensure only actual values are in the file. No suffixes eg. "X = 787878.989" = Invalid
///2. Verify the specified separator is correct for the file to be read from
///3. We could add parameter for filetype later on

namespace Multi_block_insertion
{
    public class MultiB
    {
        Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
        StreamReader coordsFile;
        string path;
        [CommandMethod("MultiB")]
        public void multiB()
        {
            Form1 form1 = new Form1();
            form1.Activate();
            form1.ShowDialog();
            StreamReader coordsFile;
        }

        public StreamReader getCoordsFile(string fileName) //Creates a stream for the selected coordinates file
        {
           
            using (FileStream coordsFileFs = File.Open(fileName, FileMode.Open, FileAccess.Read))
            {
                using (StreamReader coordsFileSr = new StreamReader(coordsFileFs))
                {
                    coordsFile = coordsFileSr;
                    return coordsFileSr;
                }
            }
        }

        public string altGetCoordsFile()
        {
            OpenFileDialog coordsFile = new OpenFileDialog("Select Coords File", null, "txt", "Coords Selection", OpenFileDialog.OpenFileDialogFlags.AllowAnyExtension);
            if (coordsFile.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                throw new System.Exception("Error or User Cancelled");
            }

            path = coordsFile.Filename.ToString();
            return path;


        }

        public Dictionary<int, string[]> createCoordsList(string separator) //This method separates the stream into coords/attributes for each block
        {
            Dictionary<int, string[]> coordsList = new Dictionary<int, string[]>();
            int numOfLines = calculateLinesInStream();  //Assign the number of lines in the stream to this integer

            StreamReader str = new StreamReader(File.Open(path, FileMode.Open));
            for (int i = 1; i < numOfLines; i++)//Loop for splitting each line into individual components - coordinates, attributes etc
            {

                string thisLine = str.ReadLine();
                int charactersThisLine = thisLine.Length;
                Queue<char> thisLineQueue = new Queue<char>(thisLine.ToCharArray());//Convert to a queue for brevity of manipulation
                int numOfCharOnThisLine = thisLineQueue.Count;//Count of the characters so we know when to quit
                int numOfSeparatorsOnThisLine = 0;//Count of separators so we know number of values to add in the array for this line
                foreach (Char thisChar in thisLineQueue)//Loop to count the separators
                {
                    if (thisChar.ToString() == separator)
                    {
                        numOfSeparatorsOnThisLine++;
                    }
                }
                string[] thisLinesValues = new string[numOfSeparatorsOnThisLine + 1];//An array for each of the values on this line (coords, attributes)
                bool endOfLine = false;
                string thisValue = "";
                int count = 0;
                int thisLineValues = 0;
                while (!endOfLine)//Keep looping until we reach the end of the line
                {
               
                    for (int a = 0; a < thisLineQueue.Count(); a++) //Loop to assess and extract each char of the queue
                    {
                        if (count == charactersThisLine )//Check whether we have reached the end of the line
                        {
                            coordsList.Add(charactersThisLine, thisLinesValues); //End of line reached, so add all values for the this line to the Dictionary
                            endOfLine = true;//When we "break", the exit conditions for while(!endOfLine) will be met
                            break;//Effectively ending extrapolation of this line
                        }

                        if (thisLineQueue.Peek().ToString() == separator)//If the next element is a separator we need to add thisValue to our array and reset it
                        {
                            thisLineQueue.Dequeue();
                            thisLinesValues[thisLineValues] = thisValue;
                            thisLineValues++;
                            count++;
                            thisValue = "";
                        }

                        //We now know the next element is valid and needs to be added to our string

                        thisValue += thisLineQueue.Dequeue();//So that's what we do here - concurrently removing the value from the queue
                        count++;

                    }
                }


            }
            return coordsList;
        }

        private int calculateLinesInStream()
        {
            int numOfLines = 0;
            using (StreamReader tempStream = new StreamReader(File.Open(path, FileMode.Open))) //Create a new stream using our parameter to quantify number of lines
            {
                bool isError = false;
                string tempString = "";//Populate this string with the current line of the stream
                while (true)//This Loop is to determine only the number of lines in this stream
                {
                    try
                    {
                        bool endLines = tempStream.EndOfStream;
                        if (endLines)
                        {
                            isError = true;
                            break;
                        }
                        tempString = tempStream.ReadLine();//Assigned the string for the current line of the stream
                    }

                    catch
                    {
                        throw new System.Exception("There was a problem");

                    }

                    if (tempString == null)
                    {
                        break;//The line was empty so we exit the loop
                    }

                    numOfLines++;//The line wasn't empty so we increment this integer
                }
            }
            return numOfLines;
        }

        [CommandMethod("TestFile")]
        public void testFile()
        {
            Dictionary<int, string[]> coordsList;
            using (StreamReader sr = getCoordsFile(altGetCoordsFile()))
            {
                Database db = HostApplicationServices.WorkingDatabase;
                Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

                ed.WriteMessage(sr.ToString());

                 coordsList = new Dictionary<int, string[]>(createCoordsList(" "));
            }
                foreach (KeyValuePair<int, string[]> pair in coordsList)
                {
                    for (int i = 0; i < pair.Value.Count() - 1; i++)
                    {
                        ed.WriteMessage(pair.Value[i].ToString());
                    }
                }
{

}
           
                 
        }
    }
}

wannabe

  • Guest
Re: StreamReader Problem
« Reply #3 on: April 23, 2009, 03:05:06 PM »
I've had no luck with my C# manuals but I did remember DocumentLock in the ACAD .NET API.

All will be revealed tomorrow.


Glenn R

  • Guest
Re: StreamReader Problem
« Reply #4 on: April 23, 2009, 04:19:16 PM »
Do a search on the forum for 'TextReader' - I think this will help.

Also, if you haven't purchased this, I and a few others here highly recommend it for learning C#.

wannabe

  • Guest
Re: StreamReader Problem
« Reply #5 on: April 23, 2009, 05:05:29 PM »
I've completed the Headfirst C# manual and read through C# for dummies books. It's just a case of putting it all into working practice and re-reading the sections as I go along. That's why this code is a bit shoddy. It was hard for me to plan when I haven't really got masses of actual coding experience. Although the Headfirst is practical based and kept me coding for a few months to get me up to speed.

For this code I just did a basic flow chart but neglected it and dived right in. And now, I'm thinking of ways I can condense it significantly. For example, I could just read each line of the stream straight into a list. Then do a for loop for each element of the list to split it up into each value.

Cheers for the reply.With the above in mind do you think I should still purchase the book? Does it's scope transcend what I am likely to have learned in the other two books?

And thanks also for the TextReader hint. I was interrupted with work, can you believe, as I was perusing the FileStream literature I had available and was just about to refresh myself on TextReader's functionality.

Cheers.

Glenn R

  • Guest
Re: StreamReader Problem
« Reply #6 on: April 23, 2009, 05:10:28 PM »
Hmmm...to answer succinctly.

Yes the book is better than you have.
Second, do the search as I suggested. You will some examples that will do pretty much what you want (ie reading in each line into a variable, splitting it up based on delimiters and adding to some sort of generic storage variable).

Keep at it - it's definitely worth it! :D

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: StreamReader Problem
« Reply #7 on: April 23, 2009, 05:17:04 PM »
O/T: Pro C# 2008 and the .NET 3.5 Platform is a great book (tome); I didn't care for the HeadFirst C# book.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

wannabe

  • Guest
Re: StreamReader Problem
« Reply #8 on: April 24, 2009, 03:16:41 AM »
Thanks guys. With your recommendations in mind my purchase is imminent. One obstructing factor, though is that with the new C# release and the increased dynamism, as-well-as the other new features, should I wait for an updated version of the book? (My feeling is to just buy this book and then a dedicated manual for the C# updates)

Also having read back my code and studied my manuals last night I can see my posted code is fairly verbose.

Again, thanks for the replies. I'm enthusiastic and I enjoy the challenge of coding a lot, so I'll definitely keep at it. Encouragement appreciated.

wannabe

  • Guest
Re: StreamReader Problem
« Reply #9 on: April 24, 2009, 08:25:09 AM »
Here is the revised portion of my code tha is causing me a bit of a headache. Are there any glaring problems that anyone can notice?

Code: [Select]
public static Dictionary<int, string[]> createCoordsDict(char separator)
        {
                string fileName = getFileWithAcadDialog();
                List<string> coordsAsList;
                Dictionary<int, string[]> returnDict = new Dictionary<int, string[]>();
                int dictKey = 0;

                FileStream fs = new FileStream(fileName, FileMode.Open);
                using (StreamReader str = new StreamReader(fs)) //End of using will close this and wrapped stream (fs)
                {
                    coordsAsList = new List<string>();
                    while (true)
                    {
                        string lineRead = str.ReadLine();
                        if (lineRead == null)
                            break;

                        coordsAsList.Add(lineRead);
                    }
                }

                string[] coordsAsArray = coordsAsList.ToArray();

                for (int i = 0; i < coordsAsArray.Length - 1; i++)
                {
                    char[] thisLineAsChars = coordsAsArray[i].ToCharArray();
                    Queue<char> thisLine = new Queue<char>(thisLineAsChars);
                    string currentValue = "";
                    List<string> lineList = new List<string>(); //Stores each individual value from current line once separated

                    while (true)
                    {
                        if (thisLine.Peek() == null)
                        {
                            returnDict.Add(dictKey, lineList.ToArray());
                            dictKey++;
                            break;
                        }

                        if (thisLine.Peek() != separator)
                        {
                            currentValue += thisLine.Dequeue();
                        }

                        lineList.Add(currentValue);
                        thisLine.Dequeue();
                    }

                }

                return returnDict;
           
        }

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: StreamReader Problem
« Reply #10 on: April 24, 2009, 08:50:21 AM »
Why all the conversions from lists to Arrays?
Why not just return Dictionary<int, List<string>>?
Just wondering


wannabe

  • Guest
Re: StreamReader Problem
« Reply #11 on: April 24, 2009, 10:57:25 AM »
I find it simpler to add elements to a list and easier to modify them as an array.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: StreamReader Problem
« Reply #12 on: April 24, 2009, 11:01:51 AM »
and easier to modify them as an array.

Can you elaborate on this point?

wannabe

  • Guest
Re: StreamReader Problem
« Reply #13 on: April 24, 2009, 11:16:16 AM »
Yeah sure. I'm just leaving work now. Give me a few hours.

The problem with the code was the last call to dequeue.

Speak soon.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: StreamReader Problem
« Reply #14 on: April 24, 2009, 11:21:55 AM »
Great! Thank you  :-)