2

I am trying to create a list using the FileStream/StreamReader method. Everything works fine except the price calculation is reset every time a new line is added.

I believe the issue is with the save method. I am sure it is not caused from functions in my classes, since the price is showing properly. There seems to be an issue when saving the string.

This is my read method:

public static List<Customer> ReadCustomers()
{
    // create an empty customer list
    List<Customer> customerList = new List<Customer>();
    // new Filestream
    FileStream fs = null;
    // new StreamReader
    StreamReader sr = null;
    Customer c; // for reading
    string line;
    string[] fields;
        try
        {
            fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read);
            sr = new StreamReader(fs);

            while (!sr.EndOfStream)// while there is data
            {
                line = sr.ReadLine();
                fields = line.Split(','); // split sections by commas

                c = new Customer(); // initializes customer object
                c.AccountNo = Convert.ToInt32(fields[0].Trim());
                c.CustomerName = Convert.ToString(fields[1].Trim());
                c.CustomerType = Convert.ToChar(fields[2].Trim());
                c.CustomerCharge = Convert.ToDecimal(fields[3].Trim());
                customerList.Add(c);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally // always execute
        {
            if (fs != null) fs.Close(); // close file
        }
    return customerList;
}

This is where I try to save the string...

public static void SaveCustomers(List<Customer> list)
{
    FileStream fs = null;
    StreamWriter sw = null;
    string line;

    try
    {
        fs = new FileStream(path, FileMode.Create, FileAccess.Write);
        sw = new StreamWriter(fs);
        foreach (Customer c in list)     // for each customer in the list
        {
            line = c.AccountNo.ToString() + ", " + c.CustomerName.ToString() + ", " +
                c.CustomerType.ToString() + ", " + c.CustomerCharge.ToString();  // make a line with data
            sw.WriteLine(line);         // and write it to the file
        }
    }
    catch(Exception ex)
    {
        throw ex;
    }
    finally
    {
        if (sw != null) sw.Close(); // stream writer close
        if (fs != null) fs.Close();
    }
}

Calculation:

public override decimal CalculateCharge()
{
    decimal peak;
    decimal offpeak;

    if (Kwh1 <= INDUST_BASE_HOURS)
    {
        peak = KWH_PEAK_BASE_PRICE;
    }
    else
    {
        peak = ((Kwh1 - INDUST_BASE_HOURS) * KWH_INDUST_PEAK) + KWH_PEAK_BASE_PRICE;
    }

    if (Kwh2 <= INDUST_BASE_HOURS)
    {
        offpeak = KWH_OFF_PEAK_BASE_PRICE;
    }
    else
    {
        offpeak = ((Kwh2 - INDUST_BASE_HOURS) * KWH_INDUST_OFFPEAK) + KWH_OFF_PEAK_BASE_PRICE;
    }

    return peak + offpeak;
}
gravity
  • 2,175
  • 2
  • 26
  • 34
JayG.Dev
  • 321
  • 1
  • 13
  • 1
    can you tell where you doing price calculation? – cdev Jun 26 '19 at 03:27
  • I think you miss the price calculation code and please include the customer class too. Thanks – Antonio Rodriguez Jun 26 '19 at 03:30
  • 1
    Do you know that there is [File.ReadAllText()](https://learn.microsoft.com/en-us/dotnet/api/system.io.file.readalltext) and [File.ReadAllLines()](https://learn.microsoft.com/en-us/dotnet/api/system.io.file.readalllines) method for reading text files? They made this process **MUCH** more easier. There is [File.ReadAllBytes()](https://learn.microsoft.com/en-us/dotnet/api/system.io.file.readallbytes) for all other type of files. – vasily.sib Jun 26 '19 at 03:30
  • Thanks for the comments. I'm not sure how to show the cycle without filling this entire page with code. When a customer is added it adds adds based on the customer chosen. I then pass to a calculation. I'll update my code with an example override statement. – JayG.Dev Jun 26 '19 at 13:30
  • 1
    Stick a break point in where you are outputting the price calculation and use the call stack to work backwards up the call chain to see what was called. Once you see a code segment that you think might be causing the problem you can add another break point and step through the segment in detail. While you are doing this, add the price list to the `Watch` window so you can see at what line of execution the list is modified. – Kieran Devlin Jun 26 '19 at 15:26

2 Answers2

1

In SaveCustomers(), are you sure you want to open the file:

fs = new FileStream(path, FileMode.Create, FileAccess.Write);

You may want:

fs = new FileStream(path, FileMode.Append, FileAccess.Write);

FileMode.Create will destroy the file if it exists.
FileMode.Append will append to an existing file it exists.

Maybe for the purposes of clarity around testing, you output to another file rather than the one you read in.

Ralph Willgoss
  • 11,750
  • 4
  • 64
  • 67
  • I tried this and it just duplicated the existing content. It still reset all the values as well. – JayG.Dev Jun 26 '19 at 14:00
  • ..so you want to write over all existing entries? I can't see the code but if you are calculating the new charge for each customer are you sure you setting the value for that customer in the list correctly? – Ralph Willgoss Jun 26 '19 at 14:42
  • When adding new users, everything appears to work fine: https://ibb.co/kGbjzwm. After I close, the calculations are all set to the base, as if no data has been saved: https://ibb.co/jGHrG80. This last image shows what happens when I used the FileMode.Append you suggested: https://ibb.co/JFqgNYT – JayG.Dev Jun 26 '19 at 15:27
  • can you show us the code around how CalculateCharge() is called for each customer? – Ralph Willgoss Jun 26 '19 at 15:49
  • @PixelsOfMind how did you go?, my answer is not complete so unless you give me some more information I'll need to delete it - so its not voted down – Ralph Willgoss Jun 27 '19 at 19:24
  • 1
    Hi Ralph, I've been meaning to update this. I managed to solve the issue by turning my calculation function into a variable in my copy constructor. I think that whenever I started the program it would re-loop through the calculations and reset it. Even thought it was not related to the Append suggestion, I did manage to help a classmate fix his code with this, so thank you! – JayG.Dev Jun 27 '19 at 22:02
0

Try using this by using the append parameter:

 new StreamWriter("c:\\file.txt", true);

http://msdn.microsoft.com/en-us/library/36b035cb.aspx

Or you can see related answers here, which had similar problems

C# add text to text file without rewriting it?

Kiwi
  • 45
  • 9