1

I have a code to read text file and save the data into a double array to plot graph:

string filename = openFileDialog1.FileName;
var lineCount = 0;
using (var reader = File.OpenText(@filename))
{
     string line;
     while ((line = reader.ReadLine()) != null)
     {
          var data = line.Split(',');
          GlobalDataClass.dDataArray[lineCount, 0] = double.Parse(data[0]);
          GlobalDataClass.dDataArray[lineCount, 1] = double.Parse(data[1]);

          lineCount++;
     }
     ShowGraphData(lineCount);
}

And I have created a public class that initiate the array to [2000,2]:

static class GlobalDataClass
{
    public static double[,] dDataArray = new double[2000, 2];   
    public static long iTotalReadingPoint;

}    

My text file will be like:

0,29
1,31  
2,32  
3,32
4,30  

However I want my program to detect the EOF so that the text file can contain random rows and still able to plot the graph not restricted to 2000 rows. Is it possible?please advice.TQ

isedev
  • 18,848
  • 3
  • 60
  • 59
Ren
  • 765
  • 4
  • 15
  • 42
  • Can't you use ArrayList or Generic List for this purpose ? http://msdn.microsoft.com/en-us/library/system.collections.arraylist.aspx http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx – Abhinav Ranjan Feb 19 '14 at 03:41
  • @AbhinavRanjan: `ArrayList` is very old concept and it is not typesafe as it stores the objects, and exact type information will be known at runtime only, so one should avoid using `ArrayList`. – Sudhakar Tillapudi Feb 19 '14 at 03:50
  • @SudhakarTillapudi Just do List and you'll be fine because it will be type safe – Dan Drews Feb 19 '14 at 03:54
  • @DanDrews: Yes Generic List is Type Safe becuase one should provide the Type information while Declaring it ex:`List list=new List();` – Sudhakar Tillapudi Feb 19 '14 at 03:55

3 Answers3

1

The StreamReader class has a boolean property named EndOfStream that is essentially EoF for FileStream objects, and there's the Peek() method which is usually the standard way of reading until EoF.

var reader = File.OpenText( ... );

while( reader.Peek() != -1 ) //Peek() returns -1 on EoF or if the stream is not seekable.
{
    var line = reader.ReadLine();
    ...
}

However reading from the file isn't really the problem if you don't want to be restricted to 2,000 lines. You might consider using a generic container of some flavour. For example:

using System.Collections.Generic;

string line = "12,34";
var dDataList = new List<KeyValuePair<double, double>>();
string[] parts = line.Split( ',' );
dDataList.Add( new KeyValuePair<double, double>( Double.Parse( parts[0] ), Double.Parse( parts[1] ) ) );

...

foreach( var pair in dDataList )
    Console.WriteLine( "{0} => {1}", pair.Key, pair.Value ); // 12 => 34

Will let you add as many pairs of doubles as you want, within reason, without having to fiddle with array resizing/copying or any of that nasty business. It's generally considered good practice to use a container like List<T> when dealing with an unknown amount of data, and to use arrays when you know exactly how much data you're going to have or the absolute maximum amount of data you can have.

  • Are there any possible way other than using array List method? – Ren Feb 19 '14 at 05:32
  • @Ren any reason you are trying to avoid Lists? it is the correct solution to your problem. – Kaushal De Silva Feb 19 '14 at 05:46
  • because the public class already declare as double[,], and there's many files that refer to this public class. And I only able to modify the function. Is it impossible to do it without using List? – Ren Feb 19 '14 at 05:54
1

I think you're asking your question a bit wrong; The problem you have is that you are declaring an array of 2000 unit fixed length, but you actually want it to be dynamic length. As Abhinav said, a list may work for you:

firstly, you might consider creating a class/struct for your coordinates:

public class Coordinate
{
    public double x;
    public double y;    
}  

Then, create a list of coordinates (of 0 length initially)...

static class GlobalDataClass
{
    public static List<Coordinate> dDataArray = new List<Coordinate>();
    public static long iTotalReadingPoint;
}    

And then add Coordinate objects to your list as you find new lines..

string filename = openFileDialog1.FileName;
var lineCount = 0;
using (var reader = File.OpenText(@filename))
{
     string line;
     while ((line = reader.ReadLine()) != null)
     {
          var data = line.Split(',');
          Coordinate coord = new Coordinate();
          coord.x = double.Parse(data[0]);
          coord.y = double.Parse(data[1]);
          GlobalDataClass.dDataArray.Add(coord);
          lineCount++;
     }
     ShowGraphData(lineCount);
}
1

If you want to use same class then try given code. This is not most optimum memory usage wise but still this should work.

        string filename = openFileDialog1.FileName;
        var lineCount = 0;
        while ((line = reader.ReadLine()) != null)
        {
            if (GlobalDataClass.dDataArray.GetLength(0) == lineCount)
            {                
                double[,] newTemp = GlobalDataClass.dDataArray;
                int increaseLenght = newTemp.Length + 1000;
                GlobalDataClass.dDataArray = new double[increaseLenght, 2];
                Array.Copy(newTemp, GlobalDataClass.dDataArray, newTemp.LongLength);
            }

            var data = line.Split(',');
            GlobalDataClass.dDataArray[lineCount, 0] = double.Parse(data[0]);
            GlobalDataClass.dDataArray[lineCount, 1] = double.Parse(data[1]);
            lineCount++;
        }
  • This code return the same error when i try to load the file that have less then 2000 rows. However I think a little more modification will make this thing works..hmmm – Ren Feb 20 '14 at 00:52
  • Didn't get a chance to test it earlier as I was confident that it should work... Missed out that we have two dimensional array.. Modified code for it to work :) – Abhinav Ranjan Feb 20 '14 at 04:24